suparank 1.3.2 → 1.3.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/suparank.js +94 -3
- package/package.json +1 -1
package/bin/suparank.js
CHANGED
|
@@ -15,9 +15,74 @@ import * as fs from 'fs'
|
|
|
15
15
|
import * as path from 'path'
|
|
16
16
|
import * as os from 'os'
|
|
17
17
|
import * as readline from 'readline'
|
|
18
|
-
import { spawn } from 'child_process'
|
|
18
|
+
import { spawn, execSync } from 'child_process'
|
|
19
|
+
import { fileURLToPath } from 'url'
|
|
19
20
|
|
|
20
21
|
const SUPARANK_DIR = path.join(os.homedir(), '.suparank')
|
|
22
|
+
const VERSION_CACHE_FILE = path.join(SUPARANK_DIR, '.version-check')
|
|
23
|
+
|
|
24
|
+
// Get current package version
|
|
25
|
+
function getCurrentVersion() {
|
|
26
|
+
try {
|
|
27
|
+
const packagePath = path.join(import.meta.dirname, '..', 'package.json')
|
|
28
|
+
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf-8'))
|
|
29
|
+
return pkg.version
|
|
30
|
+
} catch {
|
|
31
|
+
return null
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Check for updates (non-blocking, cached for 1 hour)
|
|
36
|
+
async function checkForUpdates() {
|
|
37
|
+
const currentVersion = getCurrentVersion()
|
|
38
|
+
if (!currentVersion) return
|
|
39
|
+
|
|
40
|
+
// Check cache to avoid spamming npm registry
|
|
41
|
+
try {
|
|
42
|
+
if (fs.existsSync(VERSION_CACHE_FILE)) {
|
|
43
|
+
const cache = JSON.parse(fs.readFileSync(VERSION_CACHE_FILE, 'utf-8'))
|
|
44
|
+
const cacheAge = Date.now() - cache.timestamp
|
|
45
|
+
if (cacheAge < 3600000) { // 1 hour cache
|
|
46
|
+
if (cache.latest !== currentVersion && cache.latest > currentVersion) {
|
|
47
|
+
console.error(`[suparank] Update available: ${currentVersion} → ${cache.latest}`)
|
|
48
|
+
}
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} catch {}
|
|
53
|
+
|
|
54
|
+
// Fetch latest version from npm (with timeout)
|
|
55
|
+
try {
|
|
56
|
+
const controller = new AbortController()
|
|
57
|
+
const timeout = setTimeout(() => controller.abort(), 3000) // 3 second timeout
|
|
58
|
+
|
|
59
|
+
const response = await fetch('https://registry.npmjs.org/suparank/latest', {
|
|
60
|
+
signal: controller.signal
|
|
61
|
+
})
|
|
62
|
+
clearTimeout(timeout)
|
|
63
|
+
|
|
64
|
+
if (response.ok) {
|
|
65
|
+
const data = await response.json()
|
|
66
|
+
const latestVersion = data.version
|
|
67
|
+
|
|
68
|
+
// Cache the result
|
|
69
|
+
fs.mkdirSync(SUPARANK_DIR, { recursive: true })
|
|
70
|
+
fs.writeFileSync(VERSION_CACHE_FILE, JSON.stringify({
|
|
71
|
+
latest: latestVersion,
|
|
72
|
+
current: currentVersion,
|
|
73
|
+
timestamp: Date.now()
|
|
74
|
+
}))
|
|
75
|
+
|
|
76
|
+
if (latestVersion !== currentVersion && latestVersion > currentVersion) {
|
|
77
|
+
console.error(`[suparank] Update available: ${currentVersion} → ${latestVersion}`)
|
|
78
|
+
console.error('[suparank] Run: npx suparank@latest OR npx clear-npx-cache')
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
// Silently fail - don't block MCP startup
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
21
86
|
const CONFIG_FILE = path.join(SUPARANK_DIR, 'config.json')
|
|
22
87
|
const CREDENTIALS_FILE = path.join(SUPARANK_DIR, 'credentials.json')
|
|
23
88
|
const SESSION_FILE = path.join(SUPARANK_DIR, 'session.json')
|
|
@@ -35,7 +100,7 @@ const colors = {
|
|
|
35
100
|
}
|
|
36
101
|
|
|
37
102
|
// Check if running in MCP mode (no command argument = MCP server)
|
|
38
|
-
const isMCPMode = !process.argv[2] || !['setup', 'test', 'session', 'clear', 'help', '--help', '-h'].includes(process.argv[2])
|
|
103
|
+
const isMCPMode = !process.argv[2] || !['setup', 'test', 'session', 'clear', 'update', 'version', '-v', '--version', 'help', '--help', '-h'].includes(process.argv[2])
|
|
39
104
|
|
|
40
105
|
function log(message, color = 'reset') {
|
|
41
106
|
// In MCP mode, use stderr to avoid breaking JSON protocol
|
|
@@ -344,7 +409,10 @@ function clearSession() {
|
|
|
344
409
|
}
|
|
345
410
|
}
|
|
346
411
|
|
|
347
|
-
function runMCP() {
|
|
412
|
+
async function runMCP() {
|
|
413
|
+
// Check for updates in background (non-blocking)
|
|
414
|
+
checkForUpdates()
|
|
415
|
+
|
|
348
416
|
const config = loadConfig()
|
|
349
417
|
|
|
350
418
|
if (!config) {
|
|
@@ -412,6 +480,27 @@ switch (command) {
|
|
|
412
480
|
case 'clear':
|
|
413
481
|
clearSession()
|
|
414
482
|
break
|
|
483
|
+
case 'update':
|
|
484
|
+
logHeader('Updating Suparank')
|
|
485
|
+
log('Clearing npx cache and fetching latest version...', 'yellow')
|
|
486
|
+
try {
|
|
487
|
+
execSync('rm -rf ~/.npm/_npx', { stdio: 'inherit' })
|
|
488
|
+
log('Cache cleared!', 'green')
|
|
489
|
+
log('Next run will use the latest version.', 'dim')
|
|
490
|
+
// Also clear version cache
|
|
491
|
+
if (fs.existsSync(VERSION_CACHE_FILE)) {
|
|
492
|
+
fs.unlinkSync(VERSION_CACHE_FILE)
|
|
493
|
+
}
|
|
494
|
+
} catch (e) {
|
|
495
|
+
log(`Update failed: ${e.message}`, 'red')
|
|
496
|
+
}
|
|
497
|
+
break
|
|
498
|
+
case 'version':
|
|
499
|
+
case '-v':
|
|
500
|
+
case '--version':
|
|
501
|
+
const ver = getCurrentVersion()
|
|
502
|
+
console.log(ver || 'unknown')
|
|
503
|
+
break
|
|
415
504
|
case 'help':
|
|
416
505
|
case '--help':
|
|
417
506
|
case '-h':
|
|
@@ -424,6 +513,8 @@ switch (command) {
|
|
|
424
513
|
log(' test Test API connection', 'dim')
|
|
425
514
|
log(' session View current session state', 'dim')
|
|
426
515
|
log(' clear Clear session state', 'dim')
|
|
516
|
+
log(' update Clear cache and update to latest', 'dim')
|
|
517
|
+
log(' version Show current version', 'dim')
|
|
427
518
|
log(' help Show this help message', 'dim')
|
|
428
519
|
break
|
|
429
520
|
default:
|