vibeteam 0.2.1 → 0.2.3

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/bin/cli.js CHANGED
@@ -25,10 +25,102 @@ import { dirname, resolve, join, basename } from 'path'
25
25
  import { fileURLToPath } from 'url'
26
26
  import { existsSync, mkdirSync, readFileSync } from 'fs'
27
27
  import { homedir } from 'os'
28
+ import * as readline from 'readline'
28
29
 
29
30
  const __dirname = dirname(fileURLToPath(import.meta.url))
30
31
  const ROOT = resolve(__dirname, '..')
31
32
 
33
+ // ============================================================================
34
+ // Update Check
35
+ // ============================================================================
36
+
37
+ async function checkForUpdates() {
38
+ // Skip update check for certain commands
39
+ const args = process.argv.slice(2)
40
+ if (args.includes('--help') || args.includes('-h') ||
41
+ args.includes('--version') || args.includes('-v') ||
42
+ args.includes('--hook-path') ||
43
+ args.includes('--skip-update-check')) {
44
+ return
45
+ }
46
+
47
+ try {
48
+ // Get current version
49
+ const pkg = JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8'))
50
+ const currentVersion = pkg.version
51
+
52
+ // Get latest version from npm (with timeout)
53
+ let latestVersion
54
+ try {
55
+ latestVersion = execSync('npm show vibeteam version 2>/dev/null', {
56
+ encoding: 'utf-8',
57
+ timeout: 5000
58
+ }).trim()
59
+ } catch {
60
+ // Network error or timeout - skip update check silently
61
+ return
62
+ }
63
+
64
+ if (!latestVersion || latestVersion === currentVersion) {
65
+ return
66
+ }
67
+
68
+ // Compare versions (simple semver comparison)
69
+ const current = currentVersion.split('.').map(Number)
70
+ const latest = latestVersion.split('.').map(Number)
71
+
72
+ let needsUpdate = false
73
+ for (let i = 0; i < 3; i++) {
74
+ if ((latest[i] || 0) > (current[i] || 0)) {
75
+ needsUpdate = true
76
+ break
77
+ } else if ((latest[i] || 0) < (current[i] || 0)) {
78
+ break
79
+ }
80
+ }
81
+
82
+ if (!needsUpdate) {
83
+ return
84
+ }
85
+
86
+ // Prompt user
87
+ console.log(`\n New version available: ${currentVersion} → ${latestVersion}`)
88
+
89
+ const answer = await askQuestion(' Update now? (y/n): ')
90
+
91
+ if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
92
+ console.log('\n Updating vibeteam...\n')
93
+ try {
94
+ execSync('npm install -g vibeteam@latest', { stdio: 'inherit' })
95
+ console.log('\n Update complete! Please run vibeteam again.\n')
96
+ process.exit(0)
97
+ } catch (e) {
98
+ console.error('\n Update failed. Try manually: npm install -g vibeteam@latest\n')
99
+ }
100
+ } else {
101
+ console.log() // Add spacing
102
+ }
103
+ } catch {
104
+ // Any error in update check - continue silently
105
+ }
106
+ }
107
+
108
+ function askQuestion(question) {
109
+ return new Promise((resolve) => {
110
+ const rl = readline.createInterface({
111
+ input: process.stdin,
112
+ output: process.stdout
113
+ })
114
+ rl.question(question, (answer) => {
115
+ rl.close()
116
+ resolve(answer)
117
+ })
118
+ })
119
+ }
120
+
121
+ // Run update check before anything else
122
+ await checkForUpdates()
123
+
32
124
  // ============================================================================
33
125
  // Health Checks
34
126
  // ============================================================================
@@ -124,6 +216,7 @@ Options:
124
216
  --help, -h Show this help message
125
217
  --version, -v Show version
126
218
  --hook-path Print path to hook script (for manual setup)
219
+ --skip-update-check Skip the automatic update check
127
220
 
128
221
  Environment Variables:
129
222
  VIBETEAM_PORT WebSocket server port (default: 4003)
@@ -773,7 +866,149 @@ console.log(`
773
866
  ╰─────────────────────────────────────╯
774
867
  `)
775
868
 
776
- // Run health checks
869
+ // ============================================================================
870
+ // Critical Dependency Check (blocks startup if missing)
871
+ // ============================================================================
872
+
873
+ function detectPackageManager() {
874
+ const platform = process.platform
875
+
876
+ if (platform === 'darwin') {
877
+ // macOS - check for brew
878
+ try {
879
+ execSync('which brew', { stdio: 'ignore' })
880
+ return { name: 'brew', install: (pkg) => `brew install ${pkg}` }
881
+ } catch {
882
+ return null
883
+ }
884
+ } else if (platform === 'linux') {
885
+ // Linux - check for apt, then yum/dnf
886
+ try {
887
+ execSync('which apt', { stdio: 'ignore' })
888
+ return { name: 'apt', install: (pkg) => `sudo apt install -y ${pkg}` }
889
+ } catch {
890
+ try {
891
+ execSync('which dnf', { stdio: 'ignore' })
892
+ return { name: 'dnf', install: (pkg) => `sudo dnf install -y ${pkg}` }
893
+ } catch {
894
+ try {
895
+ execSync('which yum', { stdio: 'ignore' })
896
+ return { name: 'yum', install: (pkg) => `sudo yum install -y ${pkg}` }
897
+ } catch {
898
+ return null
899
+ }
900
+ }
901
+ }
902
+ }
903
+ return null
904
+ }
905
+
906
+ async function installDependency(pkgManager, depName) {
907
+ const cmd = pkgManager.install(depName)
908
+ console.log(` Running: ${cmd}`)
909
+ console.log()
910
+
911
+ try {
912
+ execSync(cmd, { stdio: 'inherit' })
913
+ return true
914
+ } catch (e) {
915
+ console.log(` ✗ Failed to install ${depName}`)
916
+ return false
917
+ }
918
+ }
919
+
920
+ async function checkRequiredDependencies() {
921
+ const missing = []
922
+
923
+ // Check tmux (REQUIRED - agents won't spawn without it)
924
+ if (!checkTmux()) {
925
+ missing.push({
926
+ name: 'tmux',
927
+ reason: 'Required for running Claude agents in background sessions',
928
+ })
929
+ }
930
+
931
+ // Check jq (REQUIRED - hooks won't work without it)
932
+ if (!checkJq()) {
933
+ missing.push({
934
+ name: 'jq',
935
+ reason: 'Required for Claude Code hooks to capture events',
936
+ })
937
+ }
938
+
939
+ if (missing.length === 0) {
940
+ return true // All good
941
+ }
942
+
943
+ // Show what's missing
944
+ console.log(' ╭─────────────────────────────────────╮')
945
+ console.log(' │ Missing Required Dependencies │')
946
+ console.log(' ╰─────────────────────────────────────╯')
947
+ console.log()
948
+
949
+ for (const dep of missing) {
950
+ console.log(` ✗ ${dep.name} - ${dep.reason}`)
951
+ }
952
+ console.log()
953
+
954
+ // Detect package manager
955
+ const pkgManager = detectPackageManager()
956
+
957
+ if (pkgManager) {
958
+ const answer = await askQuestion(` Install missing dependencies using ${pkgManager.name}? (y/n): `)
959
+
960
+ if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
961
+ console.log()
962
+
963
+ let allInstalled = true
964
+ for (const dep of missing) {
965
+ const success = await installDependency(pkgManager, dep.name)
966
+ if (!success) {
967
+ allInstalled = false
968
+ }
969
+ }
970
+
971
+ if (allInstalled) {
972
+ console.log()
973
+ console.log(' ✓ All dependencies installed successfully!')
974
+ console.log()
975
+ return true
976
+ } else {
977
+ console.log()
978
+ console.log(' Some dependencies failed to install. Please install them manually.')
979
+ process.exit(1)
980
+ }
981
+ }
982
+ } else {
983
+ // No package manager detected - show manual instructions
984
+ console.log(' Could not detect package manager. Please install manually:')
985
+ console.log()
986
+ console.log(' macOS: brew install tmux jq')
987
+ console.log(' Ubuntu: sudo apt install tmux jq')
988
+ console.log(' Fedora: sudo dnf install tmux jq')
989
+ console.log()
990
+ }
991
+
992
+ // Ask if they want to continue anyway
993
+ const continueAnswer = await askQuestion(' Continue without these dependencies? (y/n): ')
994
+
995
+ if (continueAnswer.toLowerCase() === 'y' || continueAnswer.toLowerCase() === 'yes') {
996
+ console.log()
997
+ console.log(' ⚠ Continuing without all dependencies - some features may not work!')
998
+ console.log()
999
+ return true
1000
+ }
1001
+
1002
+ console.log()
1003
+ console.log(' Install the missing dependencies and run vibeteam again.')
1004
+ console.log()
1005
+ process.exit(1)
1006
+ }
1007
+
1008
+ // Check dependencies before starting
1009
+ await checkRequiredDependencies()
1010
+
1011
+ // Run health checks (warnings only)
777
1012
  printHealthCheck()
778
1013
 
779
1014
  console.log(`Starting server on port ${port}...`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibeteam",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "3D visualization of Claude Code as an interactive workshop",
5
5
  "author": "asara",
6
6
  "license": "MIT",
Binary file