slackhive 0.1.30 → 0.1.32
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/commands/init.js +53 -93
- package/dist/index.js +3 -1
- package/package.json +1 -1
package/dist/commands/init.js
CHANGED
|
@@ -382,119 +382,79 @@ async function init(opts) {
|
|
|
382
382
|
console.log('');
|
|
383
383
|
}
|
|
384
384
|
/**
|
|
385
|
-
* Runs `docker compose up -d --build
|
|
386
|
-
* Shows
|
|
387
|
-
*
|
|
388
|
-
* @param {string} cwd - The project directory.
|
|
389
|
-
* @param {string} displayDir - Display name for error message.
|
|
390
|
-
* @returns {Promise<void>}
|
|
385
|
+
* Runs `docker compose up -d --build`.
|
|
386
|
+
* Shows a single updating spinner line with the current build step.
|
|
387
|
+
* Docker's raw progress output is suppressed to keep the terminal clean.
|
|
391
388
|
*/
|
|
392
389
|
function runDockerBuild(cwd, displayDir) {
|
|
393
|
-
return new Promise((resolve
|
|
394
|
-
const proc = (0, child_process_1.spawn)('docker', ['compose', 'up', '-d', '--build'], {
|
|
390
|
+
return new Promise((resolve) => {
|
|
391
|
+
const proc = (0, child_process_1.spawn)('docker', ['compose', 'up', '-d', '--build', '--progress', 'plain'], {
|
|
395
392
|
cwd,
|
|
396
393
|
env: { ...process.env },
|
|
397
394
|
});
|
|
398
|
-
const stepPattern = /^#\d+ \[([^\]]+)\] (.+)/;
|
|
399
|
-
const donePattern = /^\s*(✔|Container .+ (Started|Running|Healthy)|Image .+ Built)/i;
|
|
400
|
-
let lastStep = '';
|
|
401
|
-
const processLine = (line) => {
|
|
402
|
-
const trimmed = line.trim();
|
|
403
|
-
if (!trimmed || trimmed.startsWith('#') && trimmed.includes('CACHED'))
|
|
404
|
-
return;
|
|
405
|
-
const stepMatch = stepPattern.exec(trimmed);
|
|
406
|
-
if (stepMatch) {
|
|
407
|
-
const label = ` ${chalk_1.default.dim(stepMatch[1])} ${stepMatch[2]}`;
|
|
408
|
-
if (label !== lastStep) {
|
|
409
|
-
process.stdout.write('\r\x1b[K' + label.slice(0, process.stdout.columns - 2));
|
|
410
|
-
lastStep = label;
|
|
411
|
-
}
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
if (donePattern.test(trimmed)) {
|
|
415
|
-
process.stdout.write('\r\x1b[K');
|
|
416
|
-
console.log(' ' + chalk_1.default.green('✓') + ' ' + trimmed.replace(/^✔\s*/, '').replace(/Container /, ''));
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
395
|
const startTime = Date.now();
|
|
420
396
|
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
421
397
|
let frameIdx = 0;
|
|
422
398
|
let currentStep = 'Building images';
|
|
423
|
-
const
|
|
399
|
+
const spinnerInterval = setInterval(() => {
|
|
424
400
|
const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
|
425
401
|
const frame = frames[frameIdx++ % frames.length];
|
|
426
|
-
process.stdout.
|
|
402
|
+
const cols = process.stdout.columns || 80;
|
|
403
|
+
const line = ` ${chalk_1.default.hex('#D97757')(frame)} ${currentStep} ${chalk_1.default.gray(elapsed + 's')}`;
|
|
404
|
+
process.stdout.write(`\r\x1b[K${line.slice(0, cols - 1)}`);
|
|
427
405
|
}, 80);
|
|
428
|
-
let
|
|
429
|
-
let stderrBuf = '';
|
|
406
|
+
let buf = '';
|
|
430
407
|
const errorLines = [];
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const lines =
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if (m)
|
|
451
|
-
currentStep = `${m[1]} — ${m[2].slice(0, 40)}`;
|
|
452
|
-
if (/error/i.test(line) && line.trim())
|
|
453
|
-
errorLines.push(line.trim());
|
|
454
|
-
});
|
|
455
|
-
});
|
|
408
|
+
const onData = (chunk) => {
|
|
409
|
+
buf += chunk.toString().replace(/\x1b\[[0-9;]*[a-zA-Z]/g, ''); // strip ANSI
|
|
410
|
+
const lines = buf.split('\n');
|
|
411
|
+
buf = lines.pop() ?? '';
|
|
412
|
+
for (const raw of lines) {
|
|
413
|
+
const line = raw.trim();
|
|
414
|
+
if (!line)
|
|
415
|
+
continue;
|
|
416
|
+
// Extract meaningful step: "#5 [runner 3/6] RUN npm ci"
|
|
417
|
+
const stepMatch = /^#\d+\s+\[([^\]]+)\]\s+(.+)/.exec(line);
|
|
418
|
+
if (stepMatch) {
|
|
419
|
+
currentStep = `${chalk_1.default.dim(stepMatch[1])} ${stepMatch[2].slice(0, 45)}`;
|
|
420
|
+
}
|
|
421
|
+
if (/error/i.test(line))
|
|
422
|
+
errorLines.push(line);
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
proc.stdout.on('data', onData);
|
|
426
|
+
proc.stderr.on('data', onData);
|
|
456
427
|
proc.on('close', (code) => {
|
|
457
|
-
clearInterval(
|
|
428
|
+
clearInterval(spinnerInterval);
|
|
458
429
|
process.stdout.write('\r\x1b[K');
|
|
459
430
|
if (code === 0) {
|
|
460
431
|
console.log(' ' + chalk_1.default.green('✓') + ' All services started');
|
|
461
432
|
resolve();
|
|
433
|
+
return;
|
|
462
434
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
console.log('');
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
console.log(chalk_1.default.yellow(' Cause: Network error while pulling Docker images.'));
|
|
484
|
-
console.log(chalk_1.default.gray(' Fix: Check your internet connection and retry.'));
|
|
485
|
-
}
|
|
486
|
-
else if (allErrors.includes('memory') || allErrors.includes('oom')) {
|
|
487
|
-
console.log(chalk_1.default.yellow(' Cause: Docker ran out of memory.'));
|
|
488
|
-
console.log(chalk_1.default.gray(' Fix: Increase Docker Desktop memory in Settings Resources (4GB+ recommended).'));
|
|
489
|
-
}
|
|
490
|
-
else if (errorLines.length > 0) {
|
|
491
|
-
console.log(chalk_1.default.gray(' Error details:'));
|
|
492
|
-
errorLines.slice(-5).forEach(l => console.log(chalk_1.default.red(' ' + l)));
|
|
493
|
-
}
|
|
494
|
-
console.log('');
|
|
495
|
-
console.log(chalk_1.default.gray(` To retry: cd ${displayDir} && docker compose up -d --build`));
|
|
496
|
-
resolve(); // don't reject — let init finish gracefully
|
|
435
|
+
const allErrors = errorLines.join('\n').toLowerCase();
|
|
436
|
+
if (allErrors.includes('no space left') || allErrors.includes('disk full')) {
|
|
437
|
+
console.log(chalk_1.default.yellow(' Docker is out of disk space.'));
|
|
438
|
+
console.log(chalk_1.default.gray(' Fix: docker system prune -a'));
|
|
439
|
+
}
|
|
440
|
+
else if (allErrors.includes('port is already allocated') || allErrors.includes('address already in use')) {
|
|
441
|
+
const portMatch = /bind for .+:(\d+)/.exec(allErrors);
|
|
442
|
+
const port = portMatch ? portMatch[1] : 'a required port';
|
|
443
|
+
console.log(chalk_1.default.yellow(` Port ${port} is already in use.`));
|
|
444
|
+
console.log(chalk_1.default.gray(` Fix: stop the process on port ${port} and retry`));
|
|
445
|
+
}
|
|
446
|
+
else if (allErrors.includes('permission denied') || allErrors.includes('unauthorized')) {
|
|
447
|
+
console.log(chalk_1.default.yellow(' Docker permission denied — is Docker Desktop running?'));
|
|
448
|
+
}
|
|
449
|
+
else if (allErrors.includes('memory') || allErrors.includes('oom')) {
|
|
450
|
+
console.log(chalk_1.default.yellow(' Docker ran out of memory.'));
|
|
451
|
+
console.log(chalk_1.default.gray(' Fix: increase Docker Desktop memory to 4GB+ in Settings → Resources'));
|
|
452
|
+
}
|
|
453
|
+
else if (allErrors.includes('network') || allErrors.includes('timeout') || allErrors.includes('pull')) {
|
|
454
|
+
console.log(chalk_1.default.yellow(' Network error while pulling images — check your connection and retry.'));
|
|
497
455
|
}
|
|
456
|
+
console.log(chalk_1.default.gray(` To retry: cd ${displayDir} && docker compose up -d --build`));
|
|
457
|
+
resolve();
|
|
498
458
|
});
|
|
499
459
|
});
|
|
500
460
|
}
|
package/dist/index.js
CHANGED
|
@@ -17,11 +17,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
const commander_1 = require("commander");
|
|
18
18
|
const init_1 = require("./commands/init");
|
|
19
19
|
const manage_1 = require("./commands/manage");
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
|
+
const { version } = require('../package.json');
|
|
20
22
|
const program = new commander_1.Command();
|
|
21
23
|
program
|
|
22
24
|
.name('slackhive')
|
|
23
25
|
.description('CLI to install and manage SlackHive — AI agent teams on Slack')
|
|
24
|
-
.version(
|
|
26
|
+
.version(version);
|
|
25
27
|
program
|
|
26
28
|
.command('init')
|
|
27
29
|
.description('Clone SlackHive repo, configure environment, and start services')
|