slackhive 0.1.24 → 0.1.26

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/README.md CHANGED
@@ -66,7 +66,14 @@ npm install -g slackhive
66
66
  slackhive init
67
67
  ```
68
68
 
69
- The CLI will check prerequisites (Docker, Git), clone the repo, walk you through configuration, and start all services automatically. Open `http://localhost:3001` and create your first agent.
69
+ The CLI will:
70
+ 1. Check prerequisites (Docker, Docker Compose, Git, Claude Code)
71
+ 2. Clone the repository
72
+ 3. Auto-detect your Claude installation (cross-platform compatible)
73
+ 4. Walk you through configuration (API key or subscription, admin credentials)
74
+ 5. Start all services automatically
75
+
76
+ Open `http://localhost:3001` and create your first agent.
70
77
 
71
78
  ### CLI Commands
72
79
 
@@ -261,7 +268,7 @@ Open an issue before submitting large PRs so we can align on the approach.
261
268
 
262
269
  ## 🔒 Security
263
270
 
264
- Report vulnerabilities to **[aman@pelago.co](mailto:aman@pelago.co)**please don't open public issues for security bugs. We respond within 48 hours.
271
+ Use [GitHub's private vulnerability reporting](https://github.com/pelago-labs/slackhive/security/advisories/new) — click **"Report a vulnerability"** on the Security tab. Please don't open public issues for security bugs. We respond within 48 hours.
265
272
 
266
273
  ---
267
274
 
@@ -12,10 +12,100 @@ exports.init = init;
12
12
  const child_process_1 = require("child_process");
13
13
  const fs_1 = require("fs");
14
14
  const path_1 = require("path");
15
+ const os_1 = require("os");
15
16
  const chalk_1 = __importDefault(require("chalk"));
16
17
  const ora_1 = __importDefault(require("ora"));
17
18
  const prompts_1 = __importDefault(require("prompts"));
18
- const REPO_URL = 'https://github.com/amansrivastava17/slackhive.git';
19
+ const REPO_URL = 'https://github.com/pelago-labs/slackhive.git';
20
+ /**
21
+ * Simple Claude installation detection for Linux.
22
+ * Uses the binary directly without module path detection.
23
+ */
24
+ function detectClaudeInstallationLinux() {
25
+ let claudeBin;
26
+ try {
27
+ claudeBin = (0, child_process_1.execSync)('which claude', { encoding: 'utf-8' }).trim();
28
+ }
29
+ catch {
30
+ throw new Error('Claude Code not found. Please install Claude Code first.');
31
+ }
32
+ if (!claudeBin) {
33
+ throw new Error('Claude Code not found. Please install Claude Code first.');
34
+ }
35
+ // For Linux, we don't need to detect the module path - just use the binary directly
36
+ // The Docker container will use the mounted binary
37
+ return { claudeBin, claudeModulePath: '' };
38
+ }
39
+ /**
40
+ * Advanced Claude installation detection for macOS.
41
+ * Finds both the binary and module directory automatically with symlink resolution.
42
+ */
43
+ function detectClaudeInstallationMacOS() {
44
+ // Find Claude binary
45
+ let claudeBin;
46
+ try {
47
+ claudeBin = (0, child_process_1.execSync)('which claude', { encoding: 'utf-8' }).trim();
48
+ }
49
+ catch {
50
+ throw new Error('Claude Code not found. Please install Claude Code first.');
51
+ }
52
+ if (!claudeBin) {
53
+ throw new Error('Claude Code not found. Please install Claude Code first.');
54
+ }
55
+ let claudeModulePath;
56
+ // Check if it's a symlink and resolve it
57
+ if ((0, fs_1.existsSync)(claudeBin)) {
58
+ try {
59
+ const target = (0, fs_1.readlinkSync)(claudeBin);
60
+ // Handle relative paths
61
+ const resolvedTarget = target.startsWith('/') ? target : (0, path_1.join)((0, path_1.dirname)(claudeBin), target);
62
+ // Extract module directory from cli.js path
63
+ claudeModulePath = (0, path_1.dirname)(resolvedTarget);
64
+ }
65
+ catch {
66
+ // Not a symlink, try common installation paths
67
+ const possiblePaths = [
68
+ '/usr/local/lib/node_modules/@anthropic-ai/claude-code',
69
+ '/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code',
70
+ (0, path_1.join)(process.env.HOME || '~', '.local/lib/node_modules/@anthropic-ai/claude-code'),
71
+ '/usr/lib/node_modules/@anthropic-ai/claude-code',
72
+ ];
73
+ claudeModulePath = '';
74
+ for (const path of possiblePaths) {
75
+ if ((0, fs_1.existsSync)(path) && (0, fs_1.existsSync)((0, path_1.join)(path, 'cli.js'))) {
76
+ claudeModulePath = path;
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ else {
83
+ throw new Error(`Claude binary not found at: ${claudeBin}`);
84
+ }
85
+ if (!claudeModulePath || !(0, fs_1.existsSync)((0, path_1.join)(claudeModulePath, 'cli.js'))) {
86
+ throw new Error('Could not find Claude Code module directory.');
87
+ }
88
+ // Verify required files exist
89
+ if (!(0, fs_1.existsSync)((0, path_1.join)(claudeModulePath, 'yoga.wasm'))) {
90
+ throw new Error(`Warning: yoga.wasm not found in ${claudeModulePath}`);
91
+ }
92
+ return { claudeBin, claudeModulePath };
93
+ }
94
+ /**
95
+ * Cross-platform Claude installation detection.
96
+ * Uses different strategies based on the operating system.
97
+ */
98
+ function detectClaudeInstallation() {
99
+ const os = (0, os_1.platform)();
100
+ if (os === 'darwin') {
101
+ // macOS - use advanced detection with symlink resolution
102
+ return detectClaudeInstallationMacOS();
103
+ }
104
+ else {
105
+ // Linux and other Unix-like systems - use simple detection
106
+ return detectClaudeInstallationLinux();
107
+ }
108
+ }
19
109
  /**
20
110
  * Runs `slackhive init` — interactive setup wizard.
21
111
  *
@@ -62,7 +152,7 @@ async function init(opts) {
62
152
  else {
63
153
  const spinner = (0, ora_1.default)(' Cloning repository...').start();
64
154
  try {
65
- (0, child_process_1.execSync)(`git clone ${REPO_URL} "${dir}"`, { stdio: 'ignore' });
155
+ (0, child_process_1.execSync)(`git clone --depth 1 ${REPO_URL} "${dir}"`, { stdio: 'ignore' });
66
156
  spinner.succeed('Repository cloned');
67
157
  }
68
158
  catch {
@@ -99,25 +189,62 @@ async function init(opts) {
99
189
  });
100
190
  }
101
191
  else {
192
+ // Claude subscription mode — detect installation automatically
102
193
  const claudeDir = (0, path_1.join)(process.env.HOME || '~', '.claude');
103
194
  if (!(0, fs_1.existsSync)(claudeDir)) {
104
195
  console.log(chalk_1.default.yellow('\n warning: ~/.claude not found. Run `claude login` first, then re-run `slackhive init`.'));
105
196
  process.exit(1);
106
197
  }
107
198
  console.log(chalk_1.default.green(' ✓') + ' Found ~/.claude credentials');
108
- let claudeBinDefault = '/usr/local/bin/claude';
199
+ // Auto-detect Claude installation paths
200
+ const spinner = (0, ora_1.default)(' Detecting Claude installation...').start();
109
201
  try {
110
- const found = (0, child_process_1.execSync)('which claude', { encoding: 'utf-8' }).trim();
111
- if (found)
112
- claudeBinDefault = found;
202
+ const { claudeBin, claudeModulePath } = detectClaudeInstallation();
203
+ spinner.succeed(`Found Claude at ${claudeBin}`);
204
+ // Set these for the .env file
205
+ questions.push({
206
+ type: 'text',
207
+ name: 'claudeBin',
208
+ message: 'Path to claude binary',
209
+ initial: claudeBin,
210
+ });
211
+ // Only ask for module path on macOS (Linux uses binary directly)
212
+ if (claudeModulePath) {
213
+ questions.push({
214
+ type: 'text',
215
+ name: 'claudeModulePath',
216
+ message: 'Path to claude module',
217
+ initial: claudeModulePath,
218
+ });
219
+ }
220
+ }
221
+ catch (error) {
222
+ spinner.fail('Could not detect Claude installation');
223
+ console.log(chalk_1.default.yellow(` ${error}`));
224
+ console.log(chalk_1.default.gray(' Please provide paths manually:'));
225
+ let claudeBinDefault = '/usr/local/bin/claude';
226
+ try {
227
+ const found = (0, child_process_1.execSync)('which claude', { encoding: 'utf-8' }).trim();
228
+ if (found)
229
+ claudeBinDefault = found;
230
+ }
231
+ catch { /* use default */ }
232
+ questions.push({
233
+ type: 'text',
234
+ name: 'claudeBin',
235
+ message: 'Path to claude binary',
236
+ initial: claudeBinDefault,
237
+ });
238
+ // Only ask for module path on macOS
239
+ if ((0, os_1.platform)() === 'darwin') {
240
+ questions.push({
241
+ type: 'text',
242
+ name: 'claudeModulePath',
243
+ message: 'Path to claude module directory',
244
+ initial: '/usr/local/lib/node_modules/@anthropic-ai/claude-code',
245
+ });
246
+ }
113
247
  }
114
- catch { /* use default */ }
115
- questions.push({
116
- type: 'text',
117
- name: 'claudeBin',
118
- message: 'Path to claude binary',
119
- initial: claudeBinDefault,
120
- });
121
248
  }
122
249
  questions.push({ type: 'text', name: 'adminUsername', message: 'Admin username', initial: 'admin' }, { type: 'password', name: 'adminPassword', message: 'Admin password', validate: (v) => v.length >= 6 ? true : 'At least 6 characters' }, { type: 'text', name: 'postgresPassword', message: 'Postgres password', initial: randomSecret().slice(0, 16) }, { type: 'text', name: 'redisPassword', message: 'Redis password', initial: randomSecret().slice(0, 16) });
123
250
  const response = await (0, prompts_1.default)(questions);
@@ -132,6 +259,9 @@ async function init(opts) {
132
259
  else {
133
260
  envContent += `# Claude Code subscription — credentials from ~/.claude\n`;
134
261
  envContent += `CLAUDE_BIN=${response.claudeBin}\n`;
262
+ if (response.claudeModulePath) {
263
+ envContent += `CLAUDE_MODULE_PATH=${response.claudeModulePath}\n`;
264
+ }
135
265
  }
136
266
  envContent += `\nPOSTGRES_DB=slackhive\n`;
137
267
  envContent += `POSTGRES_USER=slackhive\n`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slackhive",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "description": "CLI to install and manage SlackHive — AI agent teams on Slack",
5
5
  "bin": {
6
6
  "slackhive": "./dist/index.js"