@_xtribe/cli 2.2.48 → 2.2.50

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.
@@ -16,7 +16,8 @@ const envScriptPath = path.join(tribeDir, 'tribe-env.sh');
16
16
  * Enhanced PATH setup with comprehensive edge case handling
17
17
  */
18
18
  class EnhancedPathSetup {
19
- constructor() {
19
+ constructor(options = {}) {
20
+ this.silent = options.silent || false;
20
21
  this.detectedShell = this.detectShell();
21
22
  this.shellConfigs = this.getShellConfigs();
22
23
  this.backupDir = path.join(tribeDir, 'backups');
@@ -169,7 +170,9 @@ fi`;
169
170
  fs.copyFileSync(configPath, backupPath);
170
171
  return backupPath;
171
172
  } catch (error) {
172
- console.warn(`Could not backup ${configPath}:`, error.message);
173
+ if (!this.silent) {
174
+ console.warn(`Could not backup ${configPath}:`, error.message);
175
+ }
173
176
  return null;
174
177
  }
175
178
  }
@@ -216,14 +219,20 @@ fi`;
216
219
  );
217
220
 
218
221
  if (hasExisting) {
219
- console.log(chalk.yellow(`⚠️ TRIBE already configured in ${configFile}`));
222
+ if (!this.silent) {
223
+ console.log(chalk.yellow(`⚠️ TRIBE already configured in ${configFile}`));
224
+ }
220
225
 
221
226
  // Check if it's working
222
227
  if (this.testPathSetup()) {
223
- console.log(chalk.green(`✅ Existing configuration is working`));
228
+ if (!this.silent) {
229
+ console.log(chalk.green(`✅ Existing configuration is working`));
230
+ }
224
231
  return true;
225
232
  } else {
226
- console.log(chalk.yellow(`🔧 Existing configuration needs fixing`));
233
+ if (!this.silent) {
234
+ console.log(chalk.yellow(`🔧 Existing configuration needs fixing`));
235
+ }
227
236
  this.cleanupOldEntries(configPath, content);
228
237
  }
229
238
  }
@@ -238,11 +247,15 @@ fi`;
238
247
  ${sourceLine}`;
239
248
 
240
249
  fs.appendFileSync(configPath, configBlock);
241
- console.log(chalk.green(`✅ Updated ${configFile}`));
250
+ if (!this.silent) {
251
+ console.log(chalk.green(`✅ Updated ${configFile}`));
252
+ }
242
253
  return true;
243
254
 
244
255
  } catch (error) {
245
- console.warn(chalk.yellow(`⚠️ Could not update ${configFile}: ${error.message}`));
256
+ if (!this.silent) {
257
+ console.warn(chalk.yellow(`⚠️ Could not update ${configFile}: ${error.message}`));
258
+ }
246
259
  continue;
247
260
  }
248
261
  }
@@ -304,7 +317,9 @@ ${sourceLine}`;
304
317
 
305
318
  if (removedCount > 0) {
306
319
  fs.writeFileSync(configPath, cleanedLines.join('\n'));
307
- console.log(chalk.blue(`🧹 Cleaned up ${removedCount} old TRIBE entries`));
320
+ if (!this.silent) {
321
+ console.log(chalk.blue(`🧹 Cleaned up ${removedCount} old TRIBE entries`));
322
+ }
308
323
  }
309
324
  }
310
325
 
@@ -375,16 +390,16 @@ ${sourceLine}`;
375
390
  * Main setup function
376
391
  */
377
392
  async setup() {
378
- const spinner = ora('🔧 Setting up enhanced PATH configuration...').start();
393
+ const spinner = this.silent ? null : ora('🔧 Setting up enhanced PATH configuration...').start();
379
394
 
380
395
  try {
381
396
  // 1. Create enhanced environment script
382
397
  this.createEnvScript();
383
- spinner.text = 'Environment script created...';
398
+ if (spinner) spinner.text = 'Environment script created...';
384
399
 
385
400
  // 2. Update shell configuration
386
401
  const configSuccess = this.updateShellConfig();
387
- spinner.text = 'Shell configuration updated...';
402
+ if (spinner) spinner.text = 'Shell configuration updated...';
388
403
 
389
404
  // 3. Test setup
390
405
  await new Promise(resolve => setTimeout(resolve, 500)); // Brief pause for file system
@@ -393,52 +408,56 @@ ${sourceLine}`;
393
408
  // 4. Generate summary
394
409
  const summary = this.generateInstallSummary();
395
410
 
396
- if (pathWorking && configSuccess) {
397
- spinner.succeed('PATH setup completed successfully');
411
+ if (!this.silent) {
412
+ if (pathWorking && configSuccess) {
413
+ spinner.succeed('PATH setup completed successfully');
398
414
 
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(', ')}`));
415
+ console.log(chalk.green('\n✅ TRIBE CLI is ready to use!'));
416
+ console.log(chalk.blue(` Shell: ${summary.shell}`));
417
+ console.log(chalk.blue(` Configured: ${summary.configuredFiles.join(', ')}`));
402
418
 
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
- });
419
+ if (summary.instructions.length > 0) {
420
+ console.log(chalk.yellow('\n📝 Next steps:'));
421
+ summary.instructions.forEach(instruction => {
422
+ console.log(chalk.cyan(` ${instruction}`));
423
+ });
424
+ }
425
+ } else {
426
+ spinner.warn('PATH setup completed with warnings');
427
+
428
+ console.log(chalk.yellow('\n⚠️ Manual configuration may be needed'));
429
+ console.log(chalk.blue(' Try running: source ~/.tribe/tribe-env.sh'));
430
+ console.log(chalk.blue(' Or restart your terminal'));
431
+
432
+ if (summary.instructions.length > 0) {
433
+ console.log(chalk.yellow('\n📝 Manual steps:'));
434
+ summary.instructions.forEach(instruction => {
435
+ console.log(chalk.cyan(` ${instruction}`));
436
+ });
437
+ }
421
438
  }
422
- }
423
439
 
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"'));
440
+ // Always provide troubleshooting info
441
+ console.log(chalk.gray('\n🔍 Troubleshooting:'));
442
+ console.log(chalk.gray(' Config backups: ~/.tribe/backups/'));
443
+ console.log(chalk.gray(' Test command: which tribe'));
444
+ console.log(chalk.gray(' Manual setup: export PATH="$HOME/.tribe/bin:$PATH"'));
445
+ }
429
446
 
430
447
  return { success: pathWorking && configSuccess, summary };
431
448
 
432
449
  } 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'));
450
+ if (!this.silent) {
451
+ if (spinner) spinner.fail('PATH setup failed');
452
+ console.error(chalk.red(`Error: ${error.message}`));
453
+
454
+ // Provide fallback instructions
455
+ console.log(chalk.yellow('\n🚨 Fallback instructions:'));
456
+ console.log(chalk.cyan(' 1. Add to your shell config (~/.zshrc or ~/.bashrc):'));
457
+ console.log(chalk.cyan(' export PATH="$HOME/.tribe/bin:$PATH"'));
458
+ console.log(chalk.cyan(' 2. Restart your terminal'));
459
+ console.log(chalk.cyan(' 3. Test with: tribe --version'));
460
+ }
442
461
 
443
462
  return { success: false, error: error.message };
444
463
  }
package/install-tribe.js CHANGED
@@ -8,6 +8,7 @@ const { execSync } = require('child_process');
8
8
  const chalk = require('chalk');
9
9
  const ora = require('ora');
10
10
  const { EnhancedPathSetup } = require('./enhanced-path-setup');
11
+ const { TribeAutoUpdater } = require('./auto-updater');
11
12
 
12
13
  // ASCII art for TRIBE
13
14
  const asciiArt = `
@@ -17,8 +18,14 @@ const asciiArt = `
17
18
  ██║ ██╔══██╗██║██╔══██╗██╔══╝
18
19
  ██║ ██║ ██║██║██████╔╝███████╗
19
20
  ╚═╝ ╚═╝ ╚═╝╚═╝╚═════╝ ╚══════╝
21
+ `;
20
22
 
21
- Learn AI Engineering • Maximum Impact • It Doesn't Have to Be Hard`;
23
+ const features = `
24
+ • Traces agent actions in folders you choose
25
+ • Automatically scrubs private data
26
+ • Gives live insights based on your usage to help you learn new skills
27
+ • We read the docs so you don't have to!
28
+ `;
22
29
 
23
30
  const platform = os.platform();
24
31
  const arch = os.arch() === 'x64' ? 'amd64' : (os.arch() === 'arm64' ? 'arm64' : os.arch());
@@ -52,7 +59,8 @@ directories.forEach(({ path: dirPath, name }) => {
52
59
  function showWelcome() {
53
60
  console.clear();
54
61
  console.log(chalk.cyan(asciiArt));
55
- console.log(chalk.gray('Master AI Engineering Through Practice\n'));
62
+ console.log(chalk.white(features));
63
+ console.log('');
56
64
  }
57
65
 
58
66
 
@@ -160,16 +168,29 @@ async function installTribeCLIQuiet() {
160
168
  await downloadFile(downloadUrl, tribeDest);
161
169
  fs.chmodSync(tribeDest, '755');
162
170
 
163
- // Also download tutor-collector binary
171
+ // Also download tutor-collector binary (CRITICAL - this is the core product!)
164
172
  const tutorCollectorDest = path.join(tribeBinDir, 'tutor-collector');
165
- const tutorCollectorUrl = `https://github.com/TRIBE-INC/tutor/releases/latest/download/tutor-collector-${platform}-${arch}`;
173
+ const tutorCollectorUrl = `https://github.com/${githubRepo}/releases/latest/download/tutor-collector-${platform}-${arch}`;
166
174
 
175
+ // Try main release first, fallback to community release if not found
167
176
  try {
168
177
  await downloadFile(tutorCollectorUrl, tutorCollectorDest);
169
- fs.chmodSync(tutorCollectorDest, '755');
170
- } catch (tutorError) {
171
- // Tutor collector is optional for basic CLI functionality
172
- console.warn('Warning: Could not download tutor-collector binary');
178
+ } catch (error) {
179
+ // Fallback to community release repo (for older releases that didn't include tutor-collector)
180
+ const communityUrl = `https://github.com/TRIBE-INC/tutor-server-community-release/releases/latest/download/tutor-collector-${platform}-${arch}`;
181
+ await downloadFile(communityUrl, tutorCollectorDest);
182
+ }
183
+ fs.chmodSync(tutorCollectorDest, '755');
184
+
185
+ // Also download tutor-server binary for self-hosting capability
186
+ const tutorServerDest = path.join(tribeBinDir, 'tutor-server');
187
+ const tutorServerUrl = `https://github.com/TRIBE-INC/tutor-server-community-release/releases/latest/download/tutor-server-${platform}-${arch}`;
188
+ try {
189
+ await downloadFile(tutorServerUrl, tutorServerDest);
190
+ fs.chmodSync(tutorServerDest, '755');
191
+ } catch (error) {
192
+ // Server binary is optional - don't fail installation if unavailable
193
+ console.warn('Warning: Could not download tutor-server binary (optional for self-hosting)');
173
194
  }
174
195
 
175
196
  // Remove macOS quarantine if needed
@@ -179,6 +200,9 @@ async function installTribeCLIQuiet() {
179
200
  if (fs.existsSync(tutorCollectorDest)) {
180
201
  execSync(`xattr -d com.apple.quarantine "${tutorCollectorDest}"`, { stdio: 'ignore' });
181
202
  }
203
+ if (fs.existsSync(tutorServerDest)) {
204
+ execSync(`xattr -d com.apple.quarantine "${tutorServerDest}"`, { stdio: 'ignore' });
205
+ }
182
206
  } catch {
183
207
  // Not critical
184
208
  }
@@ -198,7 +222,7 @@ async function setupPath() {
198
222
 
199
223
  async function setupPathQuiet() {
200
224
  try {
201
- const pathSetup = new EnhancedPathSetup();
225
+ const pathSetup = new EnhancedPathSetup({ silent: true });
202
226
  const result = await pathSetup.setup();
203
227
  if (!result.success) {
204
228
  throw new Error(result.error || 'PATH setup failed');
@@ -215,17 +239,7 @@ async function main() {
215
239
  // Handle help
216
240
  if (args.includes('--help') || args.includes('-h')) {
217
241
  console.log(chalk.bold('TRIBE CLI Installer\n'));
218
- console.log('Empower your AI coding agents and become 10x faster\n');
219
- console.log('Usage: npx @_xtribe/cli [options]\n');
220
- console.log('Options:');
221
- console.log(' --help, -h Show this help message');
222
- console.log(' --version Show version');
223
- console.log(' --check-updates Check for CLI updates');
224
- console.log(' --auto-update Update CLI to latest version');
225
- console.log('\nAuto-Update Features:');
226
- console.log(' The CLI can automatically check for and install updates');
227
- console.log(' Use --check-updates to see if a newer version is available');
228
- console.log(' Use --auto-update to download and install the latest version');
242
+ console.log('Usage: npx @_xtribe/cli\n');
229
243
  process.exit(0);
230
244
  }
231
245
 
@@ -237,23 +251,25 @@ async function main() {
237
251
 
238
252
  try {
239
253
  // Install TRIBE CLI
240
- spinner.text = 'Installing CLI...';
241
254
  const success = await installTribeCLIQuiet();
242
255
  if (!success) {
243
256
  spinner.fail('Installation failed');
244
- console.log(chalk.yellow('Please check your internet connection and try again'));
245
257
  process.exit(1);
246
258
  }
247
259
 
248
- // Setup PATH
249
- spinner.text = 'Setting up environment...';
260
+ // Setup PATH quietly
250
261
  try {
251
262
  await setupPathQuiet();
252
263
  } catch (error) {
253
- // PATH setup had issues but continue with installation
254
- console.log(chalk.yellow('⚠️ PATH setup had warnings, but installation completed'));
264
+ // Continue even if PATH setup fails
255
265
  }
256
266
 
267
+ // Auto-update silently in background (don't wait for it)
268
+ const updater = new TribeAutoUpdater();
269
+ updater.autoUpdate({ silent: true, force: false }).catch(() => {
270
+ // Silently ignore update failures
271
+ });
272
+
257
273
  spinner.succeed('Ready!');
258
274
 
259
275
  // Test if tribe command works immediately
@@ -265,22 +281,13 @@ async function main() {
265
281
  commandWorks = false;
266
282
  }
267
283
 
268
- // Show appropriate completion message
284
+ // Show minimal completion message
269
285
  if (commandWorks) {
270
- console.log(chalk.green('\n✅ TRIBE CLI is ready to use!'));
271
- console.log('Type ' + chalk.cyan.bold('tribe') + ' to get started');
286
+ console.log(chalk.green('\n✅ Ready! Type ' + chalk.cyan.bold('tribe') + ' to get started'));
272
287
  } else {
273
- console.log(chalk.yellow('\n⚠️ TRIBE CLI installed successfully!'));
274
- console.log(chalk.blue('To use the tribe command, please restart your terminal'));
275
- console.log(chalk.gray('or run: ') + chalk.cyan.bold('source ~/.tribe/tribe-env.sh'));
276
- console.log(chalk.gray('\nThen type: ') + chalk.cyan.bold('tribe') + chalk.gray(' to get started'));
288
+ console.log(chalk.yellow('\n⚠️ Restart your terminal, then type ' + chalk.cyan.bold('tribe')));
277
289
  }
278
290
 
279
- // Show auto-update information
280
- console.log(chalk.blue('\n💡 Keep your TRIBE CLI up to date:'));
281
- console.log(chalk.gray(' Check for updates: ') + chalk.cyan('npx @_xtribe/cli --check-updates'));
282
- console.log(chalk.gray(' Auto-update: ') + chalk.cyan('npx @_xtribe/cli --auto-update'));
283
-
284
291
  } catch (error) {
285
292
  spinner.fail('Installation failed');
286
293
  console.error(chalk.red(error.message));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@_xtribe/cli",
3
- "version": "2.2.48",
3
+ "version": "2.2.50",
4
4
  "description": "TRIBE - Privacy-first AI development analytics. Self-host your telemetry, skip authentication, or run completely offline. Your data stays on your machine.",
5
5
  "main": "install-tribe.js",
6
6
  "bin": {
@@ -10,7 +10,9 @@
10
10
  "setup-path": "./setup-path.js"
11
11
  },
12
12
  "scripts": {
13
- "test": "echo \"Error: no test specified\" && exit 1"
13
+ "test": "echo \"Error: no test specified\" && exit 1",
14
+ "prepublishOnly": "cp README.md README-GITHUB.md && cp NPX-README.md README.md",
15
+ "postpublish": "cp README-GITHUB.md README.md && rm -f README-GITHUB.md"
14
16
  },
15
17
  "keywords": [
16
18
  "tribe",