@_xtribe/cli 2.2.3 → 2.2.8
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/enhanced-path-setup.js +457 -0
- package/install-tribe.js +8 -58
- package/package.json +2 -1
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const { execSync } = require('child_process');
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
const ora = require('ora');
|
|
9
|
+
|
|
10
|
+
const homeDir = os.homedir();
|
|
11
|
+
const tribeDir = path.join(homeDir, '.tribe');
|
|
12
|
+
const tribeBinDir = path.join(tribeDir, 'bin');
|
|
13
|
+
const envScriptPath = path.join(tribeDir, 'tribe-env.sh');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Enhanced PATH setup with comprehensive edge case handling
|
|
17
|
+
*/
|
|
18
|
+
class EnhancedPathSetup {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.detectedShell = this.detectShell();
|
|
21
|
+
this.shellConfigs = this.getShellConfigs();
|
|
22
|
+
this.backupDir = path.join(tribeDir, 'backups');
|
|
23
|
+
this.installId = Date.now().toString();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Comprehensive shell detection
|
|
28
|
+
*/
|
|
29
|
+
detectShell() {
|
|
30
|
+
const shell = process.env.SHELL || '';
|
|
31
|
+
const parentProcess = process.env._ || '';
|
|
32
|
+
|
|
33
|
+
// Check various indicators
|
|
34
|
+
if (shell.includes('zsh') || parentProcess.includes('zsh')) {
|
|
35
|
+
return 'zsh';
|
|
36
|
+
} else if (shell.includes('bash') || parentProcess.includes('bash')) {
|
|
37
|
+
return 'bash';
|
|
38
|
+
} else if (shell.includes('fish') || parentProcess.includes('fish')) {
|
|
39
|
+
return 'fish';
|
|
40
|
+
} else if (shell.includes('tcsh') || shell.includes('csh')) {
|
|
41
|
+
return 'csh';
|
|
42
|
+
} else if (process.platform === 'win32') {
|
|
43
|
+
return 'powershell';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Fallback: try to detect from system
|
|
47
|
+
try {
|
|
48
|
+
const userShell = execSync('echo $0', { encoding: 'utf8', timeout: 1000 }).trim();
|
|
49
|
+
if (userShell.includes('zsh')) return 'zsh';
|
|
50
|
+
if (userShell.includes('bash')) return 'bash';
|
|
51
|
+
if (userShell.includes('fish')) return 'fish';
|
|
52
|
+
} catch (e) {
|
|
53
|
+
// Ignore detection failures
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return 'bash'; // Safe fallback
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get shell configuration files in priority order
|
|
61
|
+
*/
|
|
62
|
+
getShellConfigs() {
|
|
63
|
+
const configs = {
|
|
64
|
+
zsh: [
|
|
65
|
+
'.zshrc',
|
|
66
|
+
'.zprofile',
|
|
67
|
+
'.zshenv',
|
|
68
|
+
'.profile'
|
|
69
|
+
],
|
|
70
|
+
bash: [
|
|
71
|
+
'.bashrc',
|
|
72
|
+
'.bash_profile',
|
|
73
|
+
'.profile',
|
|
74
|
+
'.bash_login'
|
|
75
|
+
],
|
|
76
|
+
fish: [
|
|
77
|
+
'.config/fish/config.fish'
|
|
78
|
+
],
|
|
79
|
+
csh: [
|
|
80
|
+
'.cshrc',
|
|
81
|
+
'.tcshrc'
|
|
82
|
+
],
|
|
83
|
+
powershell: [
|
|
84
|
+
'Documents/PowerShell/Microsoft.PowerShell_profile.ps1',
|
|
85
|
+
'Documents/WindowsPowerShell/Microsoft.PowerShell_profile.ps1'
|
|
86
|
+
]
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return configs[this.detectedShell] || configs.bash;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create enhanced environment script with better detection
|
|
94
|
+
*/
|
|
95
|
+
createEnvScript() {
|
|
96
|
+
let envScript;
|
|
97
|
+
|
|
98
|
+
if (this.detectedShell === 'fish') {
|
|
99
|
+
envScript = `# TRIBE CLI Environment (Fish Shell)
|
|
100
|
+
set -l tribe_bin_dir "$HOME/.tribe/bin"
|
|
101
|
+
if test -d "$tribe_bin_dir"
|
|
102
|
+
if not contains "$tribe_bin_dir" $PATH
|
|
103
|
+
set -gx PATH "$tribe_bin_dir" $PATH
|
|
104
|
+
end
|
|
105
|
+
end`;
|
|
106
|
+
} else if (this.detectedShell === 'csh') {
|
|
107
|
+
envScript = `# TRIBE CLI Environment (C Shell)
|
|
108
|
+
set tribe_bin_dir = "$HOME/.tribe/bin"
|
|
109
|
+
if ( -d "$tribe_bin_dir" ) then
|
|
110
|
+
echo ":$PATH:" | grep -q ":$tribe_bin_dir:" || setenv PATH "$tribe_bin_dir:$PATH"
|
|
111
|
+
endif`;
|
|
112
|
+
} else if (this.detectedShell === 'powershell') {
|
|
113
|
+
envScript = `# TRIBE CLI Environment (PowerShell)
|
|
114
|
+
$TribeBinDir = "$env:USERPROFILE\\.tribe\\bin"
|
|
115
|
+
if (Test-Path $TribeBinDir) {
|
|
116
|
+
if (-not ($env:PATH -split ';' -contains $TribeBinDir)) {
|
|
117
|
+
$env:PATH = "$TribeBinDir;$env:PATH"
|
|
118
|
+
}
|
|
119
|
+
}`;
|
|
120
|
+
} else {
|
|
121
|
+
// Bash/Zsh with enhanced detection
|
|
122
|
+
envScript = `#!/bin/bash
|
|
123
|
+
# TRIBE CLI Environment
|
|
124
|
+
# Generated on $(date) - Install ID: ${this.installId}
|
|
125
|
+
|
|
126
|
+
TRIBE_BIN_DIR="$HOME/.tribe/bin"
|
|
127
|
+
|
|
128
|
+
# Enhanced PATH detection - handles edge cases
|
|
129
|
+
if [[ -d "$TRIBE_BIN_DIR" ]]; then
|
|
130
|
+
# Check if already in PATH using multiple methods
|
|
131
|
+
case ":$PATH:" in
|
|
132
|
+
*":$TRIBE_BIN_DIR:"*)
|
|
133
|
+
# Already in PATH, do nothing
|
|
134
|
+
;;
|
|
135
|
+
*)
|
|
136
|
+
# Add to PATH
|
|
137
|
+
export PATH="$TRIBE_BIN_DIR:$PATH"
|
|
138
|
+
;;
|
|
139
|
+
esac
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Validate installation
|
|
143
|
+
if command -v tribe >/dev/null 2>&1; then
|
|
144
|
+
# Optional: Set additional TRIBE environment variables
|
|
145
|
+
export TRIBE_HOME="$HOME/.tribe"
|
|
146
|
+
export TRIBE_VERSION="$(tribe version 2>/dev/null || echo 'unknown')"
|
|
147
|
+
fi`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
fs.writeFileSync(envScriptPath, envScript);
|
|
151
|
+
if (this.detectedShell !== 'powershell') {
|
|
152
|
+
fs.chmodSync(envScriptPath, '755');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Backup existing shell config before modification
|
|
158
|
+
*/
|
|
159
|
+
backupShellConfig(configPath) {
|
|
160
|
+
if (!fs.existsSync(this.backupDir)) {
|
|
161
|
+
fs.mkdirSync(this.backupDir, { recursive: true });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const configName = path.basename(configPath);
|
|
165
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
166
|
+
const backupPath = path.join(this.backupDir, `${configName}.backup.${timestamp}`);
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
fs.copyFileSync(configPath, backupPath);
|
|
170
|
+
return backupPath;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.warn(`Could not backup ${configPath}:`, error.message);
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Smart shell config modification with duplicate detection
|
|
179
|
+
*/
|
|
180
|
+
updateShellConfig() {
|
|
181
|
+
const indicators = [
|
|
182
|
+
'TRIBE CLI',
|
|
183
|
+
'tribe-env.sh',
|
|
184
|
+
'.tribe/bin',
|
|
185
|
+
'source ~/.tribe',
|
|
186
|
+
'TRIBE_BIN_DIR'
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
for (const configFile of this.shellConfigs) {
|
|
190
|
+
const configPath = path.join(homeDir, configFile);
|
|
191
|
+
|
|
192
|
+
if (!fs.existsSync(configPath)) {
|
|
193
|
+
// Create config file if it doesn't exist (for primary configs only)
|
|
194
|
+
if (configFile === this.shellConfigs[0]) {
|
|
195
|
+
try {
|
|
196
|
+
// Create parent directory if needed
|
|
197
|
+
const configDir = path.dirname(configPath);
|
|
198
|
+
if (!fs.existsSync(configDir)) {
|
|
199
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
200
|
+
}
|
|
201
|
+
fs.writeFileSync(configPath, '# Created by TRIBE installer\n');
|
|
202
|
+
} catch (error) {
|
|
203
|
+
continue; // Skip if can't create
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
continue; // Skip optional configs that don't exist
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
212
|
+
|
|
213
|
+
// Check for existing TRIBE configuration
|
|
214
|
+
const hasExisting = indicators.some(indicator =>
|
|
215
|
+
content.includes(indicator)
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
if (hasExisting) {
|
|
219
|
+
console.log(chalk.yellow(`⚠️ TRIBE already configured in ${configFile}`));
|
|
220
|
+
|
|
221
|
+
// Check if it's working
|
|
222
|
+
if (this.testPathSetup()) {
|
|
223
|
+
console.log(chalk.green(`✅ Existing configuration is working`));
|
|
224
|
+
return true;
|
|
225
|
+
} else {
|
|
226
|
+
console.log(chalk.yellow(`🔧 Existing configuration needs fixing`));
|
|
227
|
+
this.cleanupOldEntries(configPath, content);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Backup before modification
|
|
232
|
+
this.backupShellConfig(configPath);
|
|
233
|
+
|
|
234
|
+
// Add new configuration
|
|
235
|
+
const sourceLine = this.getSourceLine();
|
|
236
|
+
const configBlock = `
|
|
237
|
+
# TRIBE CLI - Added ${new Date().toISOString()}
|
|
238
|
+
${sourceLine}`;
|
|
239
|
+
|
|
240
|
+
fs.appendFileSync(configPath, configBlock);
|
|
241
|
+
console.log(chalk.green(`✅ Updated ${configFile}`));
|
|
242
|
+
return true;
|
|
243
|
+
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.warn(chalk.yellow(`⚠️ Could not update ${configFile}: ${error.message}`));
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get appropriate source line for shell type
|
|
255
|
+
*/
|
|
256
|
+
getSourceLine() {
|
|
257
|
+
if (this.detectedShell === 'fish') {
|
|
258
|
+
return 'source ~/.tribe/tribe-env.sh';
|
|
259
|
+
} else if (this.detectedShell === 'csh') {
|
|
260
|
+
return 'source ~/.tribe/tribe-env.sh';
|
|
261
|
+
} else if (this.detectedShell === 'powershell') {
|
|
262
|
+
return '. $env:USERPROFILE\\.tribe\\tribe-env.ps1';
|
|
263
|
+
} else {
|
|
264
|
+
return 'source ~/.tribe/tribe-env.sh';
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Clean up duplicate or broken TRIBE entries
|
|
270
|
+
*/
|
|
271
|
+
cleanupOldEntries(configPath, content) {
|
|
272
|
+
const lines = content.split('\n');
|
|
273
|
+
const cleanedLines = [];
|
|
274
|
+
let skipNext = false;
|
|
275
|
+
let removedCount = 0;
|
|
276
|
+
|
|
277
|
+
for (let i = 0; i < lines.length; i++) {
|
|
278
|
+
const line = lines[i];
|
|
279
|
+
|
|
280
|
+
if (skipNext) {
|
|
281
|
+
skipNext = false;
|
|
282
|
+
removedCount++;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Skip old TRIBE entries
|
|
287
|
+
if (line.includes('TRIBE CLI') ||
|
|
288
|
+
line.includes('tribe-env.sh') ||
|
|
289
|
+
line.includes('export PATH=') && line.includes('.tribe/bin') ||
|
|
290
|
+
line.includes('TRIBE_BIN_DIR')) {
|
|
291
|
+
|
|
292
|
+
removedCount++;
|
|
293
|
+
|
|
294
|
+
// Check if next line is related
|
|
295
|
+
if (i + 1 < lines.length &&
|
|
296
|
+
(lines[i + 1].includes('tribe') || lines[i + 1].trim() === '')) {
|
|
297
|
+
skipNext = true;
|
|
298
|
+
}
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
cleanedLines.push(line);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (removedCount > 0) {
|
|
306
|
+
fs.writeFileSync(configPath, cleanedLines.join('\n'));
|
|
307
|
+
console.log(chalk.blue(`🧹 Cleaned up ${removedCount} old TRIBE entries`));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Test if PATH setup is working
|
|
313
|
+
*/
|
|
314
|
+
testPathSetup() {
|
|
315
|
+
try {
|
|
316
|
+
// Test if tribe command is accessible
|
|
317
|
+
const tribePath = path.join(tribeBinDir, 'tribe');
|
|
318
|
+
if (!fs.existsSync(tribePath)) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Test if it's in PATH
|
|
323
|
+
const whichResult = execSync('which tribe 2>/dev/null || echo ""', {
|
|
324
|
+
encoding: 'utf8',
|
|
325
|
+
timeout: 2000
|
|
326
|
+
}).trim();
|
|
327
|
+
|
|
328
|
+
return whichResult.includes('.tribe/bin/tribe');
|
|
329
|
+
} catch (error) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Provide comprehensive installation summary
|
|
336
|
+
*/
|
|
337
|
+
generateInstallSummary() {
|
|
338
|
+
const summary = {
|
|
339
|
+
shell: this.detectedShell,
|
|
340
|
+
pathWorking: this.testPathSetup(),
|
|
341
|
+
envScriptExists: fs.existsSync(envScriptPath),
|
|
342
|
+
tribeBinaryExists: fs.existsSync(path.join(tribeBinDir, 'tribe')),
|
|
343
|
+
configuredFiles: [],
|
|
344
|
+
instructions: []
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
// Check which configs were modified
|
|
348
|
+
for (const configFile of this.shellConfigs) {
|
|
349
|
+
const configPath = path.join(homeDir, configFile);
|
|
350
|
+
if (fs.existsSync(configPath)) {
|
|
351
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
352
|
+
if (content.includes('tribe-env.sh')) {
|
|
353
|
+
summary.configuredFiles.push(configFile);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Generate specific instructions
|
|
359
|
+
if (!summary.pathWorking) {
|
|
360
|
+
summary.instructions.push(
|
|
361
|
+
`Restart your terminal or run: source ~/.tribe/tribe-env.sh`
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
if (summary.configuredFiles.length === 0) {
|
|
365
|
+
summary.instructions.push(
|
|
366
|
+
`Manual setup required. Add to your shell config:\n source ~/.tribe/tribe-env.sh`
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return summary;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Main setup function
|
|
376
|
+
*/
|
|
377
|
+
async setup() {
|
|
378
|
+
const spinner = ora('🔧 Setting up enhanced PATH configuration...').start();
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
// 1. Create enhanced environment script
|
|
382
|
+
this.createEnvScript();
|
|
383
|
+
spinner.text = 'Environment script created...';
|
|
384
|
+
|
|
385
|
+
// 2. Update shell configuration
|
|
386
|
+
const configSuccess = this.updateShellConfig();
|
|
387
|
+
spinner.text = 'Shell configuration updated...';
|
|
388
|
+
|
|
389
|
+
// 3. Test setup
|
|
390
|
+
await new Promise(resolve => setTimeout(resolve, 500)); // Brief pause for file system
|
|
391
|
+
const pathWorking = this.testPathSetup();
|
|
392
|
+
|
|
393
|
+
// 4. Generate summary
|
|
394
|
+
const summary = this.generateInstallSummary();
|
|
395
|
+
|
|
396
|
+
if (pathWorking && configSuccess) {
|
|
397
|
+
spinner.succeed('PATH setup completed successfully');
|
|
398
|
+
|
|
399
|
+
console.log(chalk.green('\n✅ TRIBE CLI is ready to use!'));
|
|
400
|
+
console.log(chalk.blue(` Shell: ${summary.shell}`));
|
|
401
|
+
console.log(chalk.blue(` Configured: ${summary.configuredFiles.join(', ')}`));
|
|
402
|
+
|
|
403
|
+
if (summary.instructions.length > 0) {
|
|
404
|
+
console.log(chalk.yellow('\n📝 Next steps:'));
|
|
405
|
+
summary.instructions.forEach(instruction => {
|
|
406
|
+
console.log(chalk.cyan(` ${instruction}`));
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
} else {
|
|
410
|
+
spinner.warn('PATH setup completed with warnings');
|
|
411
|
+
|
|
412
|
+
console.log(chalk.yellow('\n⚠️ Manual configuration may be needed'));
|
|
413
|
+
console.log(chalk.blue(' Try running: source ~/.tribe/tribe-env.sh'));
|
|
414
|
+
console.log(chalk.blue(' Or restart your terminal'));
|
|
415
|
+
|
|
416
|
+
if (summary.instructions.length > 0) {
|
|
417
|
+
console.log(chalk.yellow('\n📝 Manual steps:'));
|
|
418
|
+
summary.instructions.forEach(instruction => {
|
|
419
|
+
console.log(chalk.cyan(` ${instruction}`));
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Always provide troubleshooting info
|
|
425
|
+
console.log(chalk.gray('\n🔍 Troubleshooting:'));
|
|
426
|
+
console.log(chalk.gray(' Config backups: ~/.tribe/backups/'));
|
|
427
|
+
console.log(chalk.gray(' Test command: which tribe'));
|
|
428
|
+
console.log(chalk.gray(' Manual setup: export PATH="$HOME/.tribe/bin:$PATH"'));
|
|
429
|
+
|
|
430
|
+
return { success: pathWorking && configSuccess, summary };
|
|
431
|
+
|
|
432
|
+
} catch (error) {
|
|
433
|
+
spinner.fail('PATH setup failed');
|
|
434
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
435
|
+
|
|
436
|
+
// Provide fallback instructions
|
|
437
|
+
console.log(chalk.yellow('\n🚨 Fallback instructions:'));
|
|
438
|
+
console.log(chalk.cyan(' 1. Add to your shell config (~/.zshrc or ~/.bashrc):'));
|
|
439
|
+
console.log(chalk.cyan(' export PATH="$HOME/.tribe/bin:$PATH"'));
|
|
440
|
+
console.log(chalk.cyan(' 2. Restart your terminal'));
|
|
441
|
+
console.log(chalk.cyan(' 3. Test with: tribe --version'));
|
|
442
|
+
|
|
443
|
+
return { success: false, error: error.message };
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Export for use in main installer
|
|
449
|
+
module.exports = { EnhancedPathSetup };
|
|
450
|
+
|
|
451
|
+
// Run if executed directly
|
|
452
|
+
if (require.main === module) {
|
|
453
|
+
const setup = new EnhancedPathSetup();
|
|
454
|
+
setup.setup().then(result => {
|
|
455
|
+
process.exit(result.success ? 0 : 1);
|
|
456
|
+
});
|
|
457
|
+
}
|
package/install-tribe.js
CHANGED
|
@@ -7,6 +7,7 @@ const https = require('https');
|
|
|
7
7
|
const { execSync } = require('child_process');
|
|
8
8
|
const chalk = require('chalk');
|
|
9
9
|
const ora = require('ora');
|
|
10
|
+
const { EnhancedPathSetup } = require('./enhanced-path-setup');
|
|
10
11
|
|
|
11
12
|
// ASCII art for TRIBE
|
|
12
13
|
const asciiArt = `
|
|
@@ -162,69 +163,18 @@ async function installTribeCLIQuiet() {
|
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
async function setupPath() {
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
// Create PATH script
|
|
169
|
-
const envScript = `#!/bin/bash
|
|
170
|
-
# TRIBE CLI Environment
|
|
171
|
-
TRIBE_BIN_DIR="$HOME/.tribe/bin"
|
|
172
|
-
if [[ -d "$TRIBE_BIN_DIR" ]] && [[ ":$PATH:" != *":$TRIBE_BIN_DIR:"* ]]; then
|
|
173
|
-
export PATH="$TRIBE_BIN_DIR:$PATH"
|
|
174
|
-
fi`;
|
|
175
|
-
|
|
176
|
-
const envScriptPath = path.join(tribeDir, 'tribe-env.sh');
|
|
177
|
-
fs.writeFileSync(envScriptPath, envScript);
|
|
178
|
-
fs.chmodSync(envScriptPath, '755');
|
|
179
|
-
|
|
180
|
-
// Try to add to shell config
|
|
181
|
-
const shellConfig = process.env.SHELL?.includes('zsh') ? '.zshrc' : '.bashrc';
|
|
182
|
-
const rcPath = path.join(homeDir, shellConfig);
|
|
183
|
-
const sourceLine = 'source ~/.tribe/tribe-env.sh';
|
|
184
|
-
|
|
185
|
-
if (fs.existsSync(rcPath)) {
|
|
186
|
-
const content = fs.readFileSync(rcPath, 'utf8');
|
|
187
|
-
if (!content.includes(sourceLine)) {
|
|
188
|
-
fs.appendFileSync(rcPath, `\n# TRIBE CLI\n${sourceLine}\n`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
spinner.succeed('Environment ready');
|
|
193
|
-
return true;
|
|
194
|
-
} catch (error) {
|
|
195
|
-
spinner.warn('PATH setup needs manual configuration');
|
|
196
|
-
console.log(chalk.yellow('\nTo use tribe command, run:'));
|
|
197
|
-
console.log(chalk.cyan(' source ~/.tribe/tribe-env.sh\n'));
|
|
198
|
-
return false;
|
|
199
|
-
}
|
|
166
|
+
const pathSetup = new EnhancedPathSetup();
|
|
167
|
+
const result = await pathSetup.setup();
|
|
168
|
+
return result.success;
|
|
200
169
|
}
|
|
201
170
|
|
|
202
171
|
async function setupPathQuiet() {
|
|
203
172
|
try {
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if [[ -d "$TRIBE_BIN_DIR" ]] && [[ ":$PATH:" != *":$TRIBE_BIN_DIR:"* ]]; then
|
|
209
|
-
export PATH="$TRIBE_BIN_DIR:$PATH"
|
|
210
|
-
fi`;
|
|
211
|
-
|
|
212
|
-
const envScriptPath = path.join(tribeDir, 'tribe-env.sh');
|
|
213
|
-
fs.writeFileSync(envScriptPath, envScript);
|
|
214
|
-
fs.chmodSync(envScriptPath, '755');
|
|
215
|
-
|
|
216
|
-
// Try to add to shell config
|
|
217
|
-
const shellConfig = process.env.SHELL?.includes('zsh') ? '.zshrc' : '.bashrc';
|
|
218
|
-
const rcPath = path.join(homeDir, shellConfig);
|
|
219
|
-
const sourceLine = 'source ~/.tribe/tribe-env.sh';
|
|
220
|
-
|
|
221
|
-
if (fs.existsSync(rcPath)) {
|
|
222
|
-
const content = fs.readFileSync(rcPath, 'utf8');
|
|
223
|
-
if (!content.includes(sourceLine)) {
|
|
224
|
-
fs.appendFileSync(rcPath, `\n# TRIBE CLI\n${sourceLine}\n`);
|
|
225
|
-
}
|
|
173
|
+
const pathSetup = new EnhancedPathSetup();
|
|
174
|
+
const result = await pathSetup.setup();
|
|
175
|
+
if (!result.success) {
|
|
176
|
+
throw new Error(result.error || 'PATH setup failed');
|
|
226
177
|
}
|
|
227
|
-
|
|
228
178
|
return true;
|
|
229
179
|
} catch (error) {
|
|
230
180
|
throw new Error('PATH setup failed: ' + error.message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@_xtribe/cli",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.8",
|
|
4
4
|
"description": "TRIBE - Track, measure and optimize your AI coding agents to become 10x faster",
|
|
5
5
|
"main": "install-tribe.js",
|
|
6
6
|
"bin": {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"install-tribe-minimal.js",
|
|
44
44
|
"install-tribe-autolaunch.js",
|
|
45
45
|
"setup-path.js",
|
|
46
|
+
"enhanced-path-setup.js",
|
|
46
47
|
"install.sh",
|
|
47
48
|
"tribe-deployment.yaml",
|
|
48
49
|
"README.md",
|