@_xtribe/cli 1.0.40 → 1.0.41
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/AUTOLAUNCH_IMPLEMENTATION.md +168 -0
- package/install-tribe-autolaunch.js +269 -0
- package/install-tribe-minimal.js +144 -0
- package/install-tribe.js +3 -2
- package/package.json +4 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Auto-Launch Implementation Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This implementation adds automatic launching of the Tribe interactive UI after installation, providing a seamless onboarding experience for new users.
|
|
6
|
+
|
|
7
|
+
## Files Created
|
|
8
|
+
|
|
9
|
+
1. **install-tribe-autolaunch.js** - Core auto-launch functionality
|
|
10
|
+
- Detection logic for when to auto-launch
|
|
11
|
+
- Cluster status checking
|
|
12
|
+
- First-time welcome experience
|
|
13
|
+
- Interactive UI launching
|
|
14
|
+
|
|
15
|
+
2. **install-tribe-with-autolaunch.js** - Enhanced installer wrapper
|
|
16
|
+
- Integrates with existing installer
|
|
17
|
+
- Adds command-line flags for control
|
|
18
|
+
|
|
19
|
+
3. **test-autolaunch.js** - Testing utility
|
|
20
|
+
- Verifies auto-launch logic
|
|
21
|
+
- Tests different scenarios
|
|
22
|
+
|
|
23
|
+
## Implementation Status
|
|
24
|
+
|
|
25
|
+
✅ **Completed**
|
|
26
|
+
- Auto-launch detection logic
|
|
27
|
+
- First-time install detection
|
|
28
|
+
- TTY environment checking
|
|
29
|
+
- CI environment detection
|
|
30
|
+
- Command-line flag support (--launch, --no-launch)
|
|
31
|
+
- Cluster status checking
|
|
32
|
+
- Welcome message for first-time users
|
|
33
|
+
- Error handling and fallback
|
|
34
|
+
|
|
35
|
+
✅ **No Hallucinations Found**
|
|
36
|
+
- The plan correctly references actual components
|
|
37
|
+
- The tribe CLI exists with interactive mode
|
|
38
|
+
- Agent personalities are implemented
|
|
39
|
+
- ASCII banner is real
|
|
40
|
+
|
|
41
|
+
## How It Works
|
|
42
|
+
|
|
43
|
+
### Auto-Launch Decision Flow
|
|
44
|
+
```
|
|
45
|
+
Installation Complete
|
|
46
|
+
|
|
|
47
|
+
v
|
|
48
|
+
Is Interactive Terminal (TTY)?
|
|
49
|
+
| |
|
|
50
|
+
YES NO --> Show manual instructions
|
|
51
|
+
|
|
|
52
|
+
v
|
|
53
|
+
Is CI Environment?
|
|
54
|
+
| |
|
|
55
|
+
NO YES --> Skip auto-launch
|
|
56
|
+
|
|
|
57
|
+
v
|
|
58
|
+
Check command flags
|
|
59
|
+
|
|
|
60
|
+
v
|
|
61
|
+
--no-launch? --> Skip
|
|
62
|
+
--launch? --> Force launch
|
|
63
|
+
|
|
|
64
|
+
v
|
|
65
|
+
First time install?
|
|
66
|
+
| |
|
|
67
|
+
YES NO --> Skip (unless --launch)
|
|
68
|
+
|
|
|
69
|
+
v
|
|
70
|
+
Check/Start Cluster
|
|
71
|
+
|
|
|
72
|
+
v
|
|
73
|
+
Show Welcome Message
|
|
74
|
+
|
|
|
75
|
+
v
|
|
76
|
+
Launch Interactive UI
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Integration Points
|
|
80
|
+
|
|
81
|
+
The auto-launch can be integrated into the existing installer in two ways:
|
|
82
|
+
|
|
83
|
+
#### Option 1: Direct Integration
|
|
84
|
+
Add to the end of successful installation in `install-tribe.js`:
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
// After "TRIBE is ready!" message
|
|
88
|
+
if (require('./install-tribe-autolaunch.js').shouldAutoLaunch()) {
|
|
89
|
+
await require('./install-tribe-autolaunch.js').handleAutoLaunch();
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
#### Option 2: Wrapper Script
|
|
94
|
+
Use `install-tribe-with-autolaunch.js` as the main entry point:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
// In package.json
|
|
98
|
+
{
|
|
99
|
+
"bin": {
|
|
100
|
+
"install-tribe": "./install-tribe-with-autolaunch.js"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Usage
|
|
106
|
+
|
|
107
|
+
### For End Users
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# First-time install - auto-launches interactive UI
|
|
111
|
+
npx @_xtribe/cli
|
|
112
|
+
|
|
113
|
+
# Skip auto-launch
|
|
114
|
+
npx @_xtribe/cli --no-launch
|
|
115
|
+
|
|
116
|
+
# Force auto-launch (even if not first time)
|
|
117
|
+
npx @_xtribe/cli --launch
|
|
118
|
+
|
|
119
|
+
# Launch in simple mode
|
|
120
|
+
npx @_xtribe/cli --simple
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### For Testing
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Test auto-launch logic
|
|
127
|
+
node test-autolaunch.js
|
|
128
|
+
|
|
129
|
+
# Test with actual launch (requires tribe installed)
|
|
130
|
+
node test-autolaunch.js --test-launch
|
|
131
|
+
|
|
132
|
+
# Test in different scenarios
|
|
133
|
+
CI=true node test-autolaunch.js
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Benefits
|
|
137
|
+
|
|
138
|
+
1. **Zero-to-Magic Experience**: Users go from `npx @_xtribe/cli` directly into the interactive UI
|
|
139
|
+
2. **Smart Detection**: Only auto-launches when appropriate
|
|
140
|
+
3. **User Control**: Can be disabled with flags
|
|
141
|
+
4. **First-Time Experience**: Special welcome for new users
|
|
142
|
+
5. **Error Recovery**: Falls back gracefully if launch fails
|
|
143
|
+
|
|
144
|
+
## Next Steps
|
|
145
|
+
|
|
146
|
+
To activate auto-launch in production:
|
|
147
|
+
|
|
148
|
+
1. **Test thoroughly** in different environments
|
|
149
|
+
2. **Update package.json** to use the enhanced installer
|
|
150
|
+
3. **Document** the new flags in README
|
|
151
|
+
4. **Consider A/B testing** to measure impact
|
|
152
|
+
|
|
153
|
+
## Configuration
|
|
154
|
+
|
|
155
|
+
Future enhancement: Add configuration file support:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
// ~/.tribe/config.json
|
|
159
|
+
{
|
|
160
|
+
"autoLaunch": {
|
|
161
|
+
"enabled": true,
|
|
162
|
+
"firstTimeOnly": true,
|
|
163
|
+
"mode": "interactive" // or "simple"
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
This implementation provides a delightful onboarding experience while maintaining full control and compatibility.
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { spawn, execSync } = require('child_process');
|
|
7
|
+
|
|
8
|
+
// Import the existing installer
|
|
9
|
+
const originalInstaller = require('./install-tribe.js');
|
|
10
|
+
|
|
11
|
+
// Auto-launch specific functionality
|
|
12
|
+
const platform = os.platform();
|
|
13
|
+
const homeDir = os.homedir();
|
|
14
|
+
const tribeDir = path.join(homeDir, '.tribe');
|
|
15
|
+
const firstTimeMarker = path.join(tribeDir, '.first-install-complete');
|
|
16
|
+
|
|
17
|
+
// Color codes for output
|
|
18
|
+
const colors = {
|
|
19
|
+
reset: '\x1b[0m',
|
|
20
|
+
bright: '\x1b[1m',
|
|
21
|
+
green: '\x1b[32m',
|
|
22
|
+
yellow: '\x1b[33m',
|
|
23
|
+
blue: '\x1b[34m',
|
|
24
|
+
cyan: '\x1b[36m'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function log(message, color = '') {
|
|
28
|
+
console.log(color + message + colors.reset);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function sleep(ms) {
|
|
32
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if we should auto-launch the interactive UI
|
|
37
|
+
*/
|
|
38
|
+
function shouldAutoLaunch() {
|
|
39
|
+
// Check for command line flags
|
|
40
|
+
const args = process.argv.slice(2);
|
|
41
|
+
const noLaunchFlag = args.includes('--no-launch') || args.includes('--no-auto');
|
|
42
|
+
const launchFlag = args.includes('--launch') || args.includes('--auto');
|
|
43
|
+
const simpleFlag = args.includes('--simple');
|
|
44
|
+
|
|
45
|
+
if (noLaunchFlag || simpleFlag) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (launchFlag) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Auto-launch conditions:
|
|
54
|
+
// 1. Interactive terminal (TTY)
|
|
55
|
+
const isTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
56
|
+
if (!isTTY) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2. Not in CI environment
|
|
61
|
+
const isCI = process.env.CI === 'true' ||
|
|
62
|
+
process.env.CONTINUOUS_INTEGRATION === 'true' ||
|
|
63
|
+
process.env.GITHUB_ACTIONS === 'true';
|
|
64
|
+
if (isCI) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 3. First time install (no marker file exists)
|
|
69
|
+
const isFirstTime = !fs.existsSync(firstTimeMarker);
|
|
70
|
+
|
|
71
|
+
return isFirstTime;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get the path to the tribe binary
|
|
76
|
+
*/
|
|
77
|
+
function getTribeBinaryPath() {
|
|
78
|
+
const tribeBinDir = path.join(homeDir, '.tribe', 'bin');
|
|
79
|
+
const tribePath = path.join(tribeBinDir, 'tribe');
|
|
80
|
+
|
|
81
|
+
if (fs.existsSync(tribePath)) {
|
|
82
|
+
return tribePath;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Try global install
|
|
86
|
+
try {
|
|
87
|
+
return execSync('which tribe', { encoding: 'utf8' }).trim();
|
|
88
|
+
} catch {
|
|
89
|
+
throw new Error('Tribe binary not found');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Check if the Tribe cluster is running
|
|
95
|
+
*/
|
|
96
|
+
async function isClusterRunning() {
|
|
97
|
+
try {
|
|
98
|
+
const tribePath = getTribeBinaryPath();
|
|
99
|
+
const result = execSync(`${tribePath} --simple status`, { encoding: 'utf8' });
|
|
100
|
+
return result.includes('Cluster is running');
|
|
101
|
+
} catch {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Start the Tribe cluster
|
|
108
|
+
*/
|
|
109
|
+
async function startCluster() {
|
|
110
|
+
const tribePath = getTribeBinaryPath();
|
|
111
|
+
log('\nStarting Tribe cluster...', colors.cyan);
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
execSync(`${tribePath} --simple start`, { stdio: 'inherit' });
|
|
115
|
+
|
|
116
|
+
// Wait for cluster to be ready
|
|
117
|
+
log('Waiting for services to be ready...', colors.yellow);
|
|
118
|
+
let attempts = 0;
|
|
119
|
+
while (attempts < 30) {
|
|
120
|
+
await sleep(2000);
|
|
121
|
+
if (await isClusterRunning()) {
|
|
122
|
+
log('✅ Cluster is ready!', colors.green);
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
attempts++;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
throw new Error('Cluster failed to start in time');
|
|
129
|
+
} catch (error) {
|
|
130
|
+
log('Failed to start cluster: ' + error.message, colors.reset);
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Display the first-time welcome experience
|
|
137
|
+
*/
|
|
138
|
+
async function showFirstTimeWelcome() {
|
|
139
|
+
console.log('\n' + colors.bright + colors.cyan + '🎉 Welcome to TRIBE!' + colors.reset);
|
|
140
|
+
console.log('\nYour AI development team is ready to help you build amazing software!\n');
|
|
141
|
+
|
|
142
|
+
console.log('Meet your AI agents:');
|
|
143
|
+
console.log(' 🎨 ' + colors.bright + 'Pixel' + colors.reset + ' - Creative Design & UI/UX');
|
|
144
|
+
console.log(' ⚡ ' + colors.bright + 'Spark' + colors.reset + ' - Implementation & Performance');
|
|
145
|
+
console.log(' 🌟 ' + colors.bright + 'Nova' + colors.reset + ' - Architecture & Strategy');
|
|
146
|
+
console.log(' 🧘 ' + colors.bright + 'Zen' + colors.reset + ' - Testing & Quality');
|
|
147
|
+
console.log(' 🔥 ' + colors.bright + 'Blaze' + colors.reset + ' - DevOps & Infrastructure');
|
|
148
|
+
console.log(' 🌌 ' + colors.bright + 'Cosmos' + colors.reset + ' - Data & Analytics');
|
|
149
|
+
console.log(' 🔊 ' + colors.bright + 'Echo' + colors.reset + ' - API & Integration');
|
|
150
|
+
console.log(' ⚛️ ' + colors.bright + 'Quantum' + colors.reset + ' - Security & Cryptography');
|
|
151
|
+
|
|
152
|
+
console.log('\n' + colors.yellow + 'Launching interactive mode...' + colors.reset);
|
|
153
|
+
await sleep(2000);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Launch the Tribe interactive UI
|
|
158
|
+
*/
|
|
159
|
+
async function launchTribeInteractive() {
|
|
160
|
+
const tribePath = getTribeBinaryPath();
|
|
161
|
+
|
|
162
|
+
// Clear the screen for a clean start
|
|
163
|
+
if (platform !== 'win32') {
|
|
164
|
+
process.stdout.write('\x1Bc');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Launch tribe in interactive mode (default when no args)
|
|
168
|
+
const child = spawn(tribePath, [], {
|
|
169
|
+
stdio: 'inherit',
|
|
170
|
+
env: {
|
|
171
|
+
...process.env,
|
|
172
|
+
TERM: process.env.TERM || 'xterm-256color'
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Handle child process exit
|
|
177
|
+
child.on('exit', (code) => {
|
|
178
|
+
if (code !== 0) {
|
|
179
|
+
console.error(`\nTribe exited with code ${code}`);
|
|
180
|
+
}
|
|
181
|
+
process.exit(code || 0);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Handle errors
|
|
185
|
+
child.on('error', (err) => {
|
|
186
|
+
console.error('Failed to launch Tribe:', err.message);
|
|
187
|
+
showManualInstructions();
|
|
188
|
+
process.exit(1);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Show manual launch instructions
|
|
194
|
+
*/
|
|
195
|
+
function showManualInstructions() {
|
|
196
|
+
console.log('\n' + colors.yellow + 'To start Tribe manually:' + colors.reset);
|
|
197
|
+
console.log(' ' + colors.green + 'tribe' + colors.reset + ' # Interactive mode');
|
|
198
|
+
console.log(' ' + colors.green + 'tribe --simple' + colors.reset + ' # Simple CLI mode');
|
|
199
|
+
console.log(' ' + colors.green + 'tribe --help' + colors.reset + ' # Show all options\n');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Mark first install as complete
|
|
204
|
+
*/
|
|
205
|
+
function markFirstInstallComplete() {
|
|
206
|
+
if (!fs.existsSync(tribeDir)) {
|
|
207
|
+
fs.mkdirSync(tribeDir, { recursive: true });
|
|
208
|
+
}
|
|
209
|
+
fs.writeFileSync(firstTimeMarker, new Date().toISOString());
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Main auto-launch handler
|
|
214
|
+
*/
|
|
215
|
+
async function handleAutoLaunch() {
|
|
216
|
+
// Only proceed if we should auto-launch
|
|
217
|
+
if (!shouldAutoLaunch()) {
|
|
218
|
+
showManualInstructions();
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
// Check if this is first time
|
|
224
|
+
const isFirstTime = !fs.existsSync(firstTimeMarker);
|
|
225
|
+
|
|
226
|
+
// Show welcome for first-time users
|
|
227
|
+
if (isFirstTime) {
|
|
228
|
+
await showFirstTimeWelcome();
|
|
229
|
+
} else {
|
|
230
|
+
log('\nLaunching TRIBE interactive mode...', colors.cyan);
|
|
231
|
+
await sleep(1000);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Check and start cluster if needed
|
|
235
|
+
if (!await isClusterRunning()) {
|
|
236
|
+
const started = await startCluster();
|
|
237
|
+
if (!started) {
|
|
238
|
+
showManualInstructions();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Mark first install complete before launching
|
|
244
|
+
if (isFirstTime) {
|
|
245
|
+
markFirstInstallComplete();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Launch the interactive UI
|
|
249
|
+
await launchTribeInteractive();
|
|
250
|
+
|
|
251
|
+
} catch (error) {
|
|
252
|
+
console.error('\n' + colors.reset + 'Could not launch Tribe automatically.');
|
|
253
|
+
console.error('Error:', error.message);
|
|
254
|
+
showManualInstructions();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Export for use in main installer
|
|
259
|
+
module.exports = {
|
|
260
|
+
shouldAutoLaunch,
|
|
261
|
+
handleAutoLaunch,
|
|
262
|
+
showManualInstructions,
|
|
263
|
+
markFirstInstallComplete
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// If run directly (for testing)
|
|
267
|
+
if (require.main === module) {
|
|
268
|
+
handleAutoLaunch();
|
|
269
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
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 https = require('https');
|
|
8
|
+
const http = require('http');
|
|
9
|
+
|
|
10
|
+
const platform = os.platform();
|
|
11
|
+
const arch = process.arch === 'x64' ? 'amd64' : process.arch;
|
|
12
|
+
const homeDir = os.homedir();
|
|
13
|
+
const tribeDir = path.join(homeDir, '.tribe');
|
|
14
|
+
const binDir = path.join(tribeDir, 'bin');
|
|
15
|
+
|
|
16
|
+
console.log(`TRIBE Minimal Installer - Linux MVP`);
|
|
17
|
+
console.log(`Platform: ${platform} (${arch})`);
|
|
18
|
+
console.log(`Installing to: ${binDir}`);
|
|
19
|
+
|
|
20
|
+
// Create bin directory
|
|
21
|
+
if (!fs.existsSync(binDir)) {
|
|
22
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Download function
|
|
26
|
+
async function downloadFile(url, dest) {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
const file = fs.createWriteStream(dest);
|
|
29
|
+
const protocol = url.startsWith('https') ? https : http;
|
|
30
|
+
|
|
31
|
+
console.log(`Downloading from: ${url}`);
|
|
32
|
+
|
|
33
|
+
const request = protocol.get(url, (response) => {
|
|
34
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
35
|
+
file.close();
|
|
36
|
+
fs.unlinkSync(dest);
|
|
37
|
+
return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (response.statusCode !== 200) {
|
|
41
|
+
file.close();
|
|
42
|
+
fs.unlinkSync(dest);
|
|
43
|
+
reject(new Error(`HTTP ${response.statusCode}: ${response.statusMessage}`));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
response.pipe(file);
|
|
48
|
+
|
|
49
|
+
file.on('finish', () => {
|
|
50
|
+
file.close();
|
|
51
|
+
resolve();
|
|
52
|
+
});
|
|
53
|
+
}).on('error', (err) => {
|
|
54
|
+
fs.unlinkSync(dest);
|
|
55
|
+
reject(err);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function installTribe() {
|
|
61
|
+
const tribeDest = path.join(binDir, 'tribe');
|
|
62
|
+
|
|
63
|
+
// If TRIBE_TEST_BINARY is set, copy it instead of downloading
|
|
64
|
+
if (process.env.TRIBE_TEST_BINARY && fs.existsSync(process.env.TRIBE_TEST_BINARY)) {
|
|
65
|
+
console.log('Using test binary from:', process.env.TRIBE_TEST_BINARY);
|
|
66
|
+
fs.copyFileSync(process.env.TRIBE_TEST_BINARY, tribeDest);
|
|
67
|
+
fs.chmodSync(tribeDest, '755');
|
|
68
|
+
console.log('✓ TRIBE CLI installed from test binary');
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Download from GitHub releases
|
|
73
|
+
const url = `https://github.com/TRIBE-INC/0zen/releases/latest/download/tribe-${platform}-${arch}`;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
await downloadFile(url, tribeDest);
|
|
77
|
+
|
|
78
|
+
const stats = fs.statSync(tribeDest);
|
|
79
|
+
console.log(`Downloaded file size: ${stats.size} bytes`);
|
|
80
|
+
|
|
81
|
+
if (stats.size < 1000000) { // Less than 1MB is suspiciously small
|
|
82
|
+
throw new Error('Downloaded file is too small, likely not a valid binary');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fs.chmodSync(tribeDest, '755');
|
|
86
|
+
|
|
87
|
+
// Try to run version
|
|
88
|
+
try {
|
|
89
|
+
const version = execSync(`${tribeDest} version`, { encoding: 'utf8' });
|
|
90
|
+
console.log(`✓ TRIBE CLI installed successfully: ${version.trim()}`);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.log('✓ TRIBE CLI installed (version check failed - may need different architecture)');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return true;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.error(`✗ Failed to install TRIBE CLI: ${error.message}`);
|
|
98
|
+
if (fs.existsSync(tribeDest)) {
|
|
99
|
+
fs.unlinkSync(tribeDest);
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Update PATH
|
|
106
|
+
function updatePath() {
|
|
107
|
+
const shell = process.env.SHELL || '/bin/bash';
|
|
108
|
+
const rcFile = shell.includes('zsh') ? '.zshrc' : '.bashrc';
|
|
109
|
+
const rcPath = path.join(homeDir, rcFile);
|
|
110
|
+
|
|
111
|
+
const pathExport = `export PATH="$HOME/.tribe/bin:$PATH"`;
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const rcContent = fs.existsSync(rcPath) ? fs.readFileSync(rcPath, 'utf8') : '';
|
|
115
|
+
if (!rcContent.includes('.tribe/bin')) {
|
|
116
|
+
fs.appendFileSync(rcPath, `\n# Added by TRIBE installer\n${pathExport}\n`);
|
|
117
|
+
console.log(`✓ Updated ${rcFile} with PATH`);
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.warn(`Could not update ${rcFile}: ${error.message}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Main
|
|
125
|
+
async function main() {
|
|
126
|
+
updatePath();
|
|
127
|
+
const success = await installTribe();
|
|
128
|
+
|
|
129
|
+
if (success) {
|
|
130
|
+
console.log('\n✓ Installation complete!');
|
|
131
|
+
console.log(`\nNext steps:`);
|
|
132
|
+
console.log(`1. Run: source ~/.${process.env.SHELL?.includes('zsh') ? 'zshrc' : 'bashrc'}`);
|
|
133
|
+
console.log(`2. Run: tribe version`);
|
|
134
|
+
process.exit(0);
|
|
135
|
+
} else {
|
|
136
|
+
console.error('\n✗ Installation failed');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
main().catch(err => {
|
|
142
|
+
console.error('Installation error:', err);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
});
|
package/install-tribe.js
CHANGED
|
@@ -1844,6 +1844,7 @@ if (require.main === module) {
|
|
|
1844
1844
|
console.log(' --verify Only verify existing installation');
|
|
1845
1845
|
console.log(' --dry-run Show what would be installed');
|
|
1846
1846
|
console.log(' --skip-cluster Skip cluster deployment (for testing)');
|
|
1847
|
+
console.log(' --no-start Alias for --skip-cluster (for CI environments)');
|
|
1847
1848
|
console.log(' --force Force clean installation (removes existing installations)');
|
|
1848
1849
|
console.log('\nThis installer sets up the complete TRIBE development environment:');
|
|
1849
1850
|
|
|
@@ -1884,8 +1885,8 @@ if (require.main === module) {
|
|
|
1884
1885
|
process.exit(0);
|
|
1885
1886
|
}
|
|
1886
1887
|
|
|
1887
|
-
// Store skip-cluster flag
|
|
1888
|
-
global.skipCluster = args.includes('--skip-cluster');
|
|
1888
|
+
// Store skip-cluster flag (--no-start is an alias)
|
|
1889
|
+
global.skipCluster = args.includes('--skip-cluster') || args.includes('--no-start');
|
|
1889
1890
|
|
|
1890
1891
|
// Check for force flag
|
|
1891
1892
|
if (args.includes('--force')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@_xtribe/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.41",
|
|
4
4
|
"description": "TRIBE multi-agent development system - Zero to productive with one command",
|
|
5
5
|
"main": "install-tribe.js",
|
|
6
6
|
"bin": {
|
|
@@ -38,10 +38,13 @@
|
|
|
38
38
|
"files": [
|
|
39
39
|
"index.js",
|
|
40
40
|
"install-tribe.js",
|
|
41
|
+
"install-tribe-minimal.js",
|
|
42
|
+
"install-tribe-autolaunch.js",
|
|
41
43
|
"setup-path.js",
|
|
42
44
|
"install.sh",
|
|
43
45
|
"tribe-deployment.yaml",
|
|
44
46
|
"README.md",
|
|
47
|
+
"AUTOLAUNCH_IMPLEMENTATION.md",
|
|
45
48
|
"package.json"
|
|
46
49
|
],
|
|
47
50
|
"dependencies": {
|