slackhive 0.1.25 → 0.1.27
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 +9 -2
- package/dist/commands/init.js +141 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,7 +66,14 @@ npm install -g slackhive
|
|
|
66
66
|
slackhive init
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
The CLI will
|
|
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
|
-
|
|
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
|
|
package/dist/commands/init.js
CHANGED
|
@@ -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
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
|
*
|
|
@@ -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
|
-
|
|
199
|
+
// Auto-detect Claude installation paths
|
|
200
|
+
const spinner = (0, ora_1.default)(' Detecting Claude installation...').start();
|
|
109
201
|
try {
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
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`;
|