slackhive 0.1.11 → 0.1.13

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.
@@ -57,7 +57,7 @@ async function init(opts) {
57
57
  console.log(chalk_1.default.bold.hex('#D97757')(' [2/4]') + chalk_1.default.bold(' Getting SlackHive'));
58
58
  console.log('');
59
59
  if ((0, fs_1.existsSync)(dir)) {
60
- console.log(chalk_1.default.yellow(` Directory ${opts.dir} already exists — using existing`));
60
+ console.log(chalk_1.default.yellow(` note: Directory ${opts.dir} already exists — using existing`));
61
61
  }
62
62
  else {
63
63
  const spinner = (0, ora_1.default)(' Cloning repository...').start();
@@ -101,7 +101,7 @@ async function init(opts) {
101
101
  else {
102
102
  const claudeDir = (0, path_1.join)(process.env.HOME || '~', '.claude');
103
103
  if (!(0, fs_1.existsSync)(claudeDir)) {
104
- console.log(chalk_1.default.yellow('\n ~/.claude not found. Run `claude login` first, then re-run `slackhive init`.'));
104
+ console.log(chalk_1.default.yellow('\n warning: ~/.claude not found. Run `claude login` first, then re-run `slackhive init`.'));
105
105
  process.exit(1);
106
106
  }
107
107
  console.log(chalk_1.default.green(' ✓') + ' Found ~/.claude credentials');
@@ -157,7 +157,7 @@ async function init(opts) {
157
157
  if (!envContents.includes('AUTH_SECRET='))
158
158
  missingKeys.push('AUTH_SECRET');
159
159
  if (missingKeys.length > 0) {
160
- console.log(chalk_1.default.yellow(` .env is missing: ${missingKeys.join(', ')} — patching...`));
160
+ console.log(chalk_1.default.yellow(` warning: .env is missing: ${missingKeys.join(', ')} — patching...`));
161
161
  let patch = '';
162
162
  if (!envContents.includes('REDIS_PASSWORD='))
163
163
  patch += `\nREDIS_PASSWORD=${randomSecret().slice(0, 16)}\n`;
@@ -167,7 +167,7 @@ async function init(opts) {
167
167
  console.log(chalk_1.default.green(' ✓') + ' .env patched');
168
168
  }
169
169
  else {
170
- console.log(chalk_1.default.yellow(' .env already exists — skipping configuration'));
170
+ console.log(chalk_1.default.yellow(' note: .env already exists — skipping configuration'));
171
171
  }
172
172
  console.log('');
173
173
  }
@@ -176,6 +176,24 @@ async function init(opts) {
176
176
  console.log(chalk_1.default.bold.hex('#D97757')(' [4/4]') + chalk_1.default.bold(' Building & starting services'));
177
177
  console.log(chalk_1.default.gray(' This takes 3–5 minutes on first run while Docker builds images.'));
178
178
  console.log('');
179
+ // Pre-flight: check Docker has enough disk space (need ~3GB)
180
+ try {
181
+ const dfOut = (0, child_process_1.execSync)('docker system df --format "{{.Size}}"', { encoding: 'utf-8' });
182
+ void dfOut; // just checking it runs without error
183
+ }
184
+ catch {
185
+ console.log(chalk_1.default.yellow(' note: Could not check Docker disk usage — continuing anyway'));
186
+ }
187
+ // Pre-flight: warn if low disk space on host
188
+ try {
189
+ const df = (0, child_process_1.execSync)('df -k . | tail -1', { encoding: 'utf-8' }).trim();
190
+ const available = parseInt(df.split(/\s+/)[3]);
191
+ if (!isNaN(available) && available < 3 * 1024 * 1024) {
192
+ console.log(chalk_1.default.yellow(` warning: less than 3GB disk space available. Build may fail.`));
193
+ console.log('');
194
+ }
195
+ }
196
+ catch { /* non-fatal */ }
179
197
  await runDockerBuild(dir, opts.dir);
180
198
  // Wait for web UI
181
199
  const webSpinner = (0, ora_1.default)(' Waiting for web UI to be ready...').start();
@@ -201,8 +219,8 @@ async function init(opts) {
201
219
  console.log('');
202
220
  console.log(' ' + chalk_1.default.bgHex('#D97757').black.bold(' SlackHive is ready! '));
203
221
  console.log('');
204
- console.log(` ${chalk_1.default.bold('Open:')} ${chalk_1.default.cyan('http://localhost:3001')}`);
205
- console.log(` ${chalk_1.default.bold('Dir:')} ${chalk_1.default.gray(dir)}`);
222
+ console.log(` ${chalk_1.default.bold('Open:')} ${chalk_1.default.cyan('http://localhost:3001')}`);
223
+ console.log(` ${chalk_1.default.bold('Dir:')} ${chalk_1.default.gray(dir)}`);
206
224
  console.log('');
207
225
  console.log(chalk_1.default.gray(' Useful commands:'));
208
226
  console.log(chalk_1.default.gray(' slackhive start — Start services'));
@@ -235,7 +253,7 @@ function runDockerBuild(cwd, displayDir) {
235
253
  return;
236
254
  const stepMatch = stepPattern.exec(trimmed);
237
255
  if (stepMatch) {
238
- const label = ` ${chalk_1.default.gray('▸')} ${chalk_1.default.dim(stepMatch[1])} ${stepMatch[2]}`;
256
+ const label = ` ${chalk_1.default.dim(stepMatch[1])} ${stepMatch[2]}`;
239
257
  if (label !== lastStep) {
240
258
  process.stdout.write('\r\x1b[K' + label.slice(0, process.stdout.columns - 2));
241
259
  lastStep = label;
@@ -293,10 +311,34 @@ function runDockerBuild(cwd, displayDir) {
293
311
  }
294
312
  else {
295
313
  console.log(' ' + chalk_1.default.red('✗') + ' Failed to start services');
296
- if (errorLines.length > 0) {
297
- console.log('');
314
+ console.log('');
315
+ // Classify the error and give actionable guidance
316
+ const allErrors = errorLines.join('\n').toLowerCase();
317
+ if (allErrors.includes('no space left') || allErrors.includes('disk full')) {
318
+ console.log(chalk_1.default.yellow(' Cause: Docker is out of disk space.'));
319
+ console.log(chalk_1.default.gray(' Fix: Run `docker system prune -a` to free space, then retry.'));
320
+ }
321
+ else if (allErrors.includes('port is already allocated') || allErrors.includes('address already in use')) {
322
+ const portMatch = /bind for .+:(\d+)/.exec(allErrors);
323
+ const port = portMatch ? portMatch[1] : 'a required port';
324
+ console.log(chalk_1.default.yellow(` Cause: Port ${port} is already in use by another process.`));
325
+ console.log(chalk_1.default.gray(` Fix: Stop the process using port ${port}, then retry.`));
326
+ }
327
+ else if (allErrors.includes('permission denied') || allErrors.includes('unauthorized')) {
328
+ console.log(chalk_1.default.yellow(' Cause: Docker permission denied.'));
329
+ console.log(chalk_1.default.gray(' Fix: Make sure Docker Desktop is running and you are logged in.'));
330
+ }
331
+ else if (allErrors.includes('network') || allErrors.includes('timeout') || allErrors.includes('pull')) {
332
+ console.log(chalk_1.default.yellow(' Cause: Network error while pulling Docker images.'));
333
+ console.log(chalk_1.default.gray(' Fix: Check your internet connection and retry.'));
334
+ }
335
+ else if (allErrors.includes('memory') || allErrors.includes('oom')) {
336
+ console.log(chalk_1.default.yellow(' Cause: Docker ran out of memory.'));
337
+ console.log(chalk_1.default.gray(' Fix: Increase Docker Desktop memory in Settings Resources (4GB+ recommended).'));
338
+ }
339
+ else if (errorLines.length > 0) {
298
340
  console.log(chalk_1.default.gray(' Error details:'));
299
- errorLines.slice(-5).forEach(l => console.log(chalk_1.default.red(' ' + l)));
341
+ errorLines.slice(-5).forEach(l => console.log(chalk_1.default.red(' ' + l)));
300
342
  }
301
343
  console.log('');
302
344
  console.log(chalk_1.default.gray(` To retry: cd ${displayDir} && docker compose up -d --build`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slackhive",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "CLI to install and manage SlackHive — AI agent teams on Slack",
5
5
  "bin": {
6
6
  "slackhive": "./dist/index.js"