@colmbus72/yeehaw 0.1.0 → 0.2.0

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/dist/index.js CHANGED
@@ -5,9 +5,21 @@ import { execaSync } from 'execa';
5
5
  import { App } from './app.js';
6
6
  import { isInsideYeehawSession, yeehawSessionExists, createYeehawSession, attachToYeehaw, hasTmux, } from './lib/tmux.js';
7
7
  import { ensureConfigDirs } from './lib/config.js';
8
+ import { checkForUpdates, formatUpdateMessage } from './lib/update-check.js';
8
9
  function main() {
9
10
  // Ensure config directories exist
10
11
  ensureConfigDirs();
12
+ // Check for updates (non-blocking, uses cache)
13
+ try {
14
+ const updateInfo = checkForUpdates();
15
+ if (updateInfo?.updateAvailable) {
16
+ console.log('\x1b[33m%s\x1b[0m', formatUpdateMessage(updateInfo));
17
+ console.log('');
18
+ }
19
+ }
20
+ catch {
21
+ // Ignore update check errors
22
+ }
11
23
  // Check if tmux is available
12
24
  if (!hasTmux()) {
13
25
  console.error('Error: tmux is required but not installed');
@@ -0,0 +1,14 @@
1
+ export interface UpdateInfo {
2
+ updateAvailable: boolean;
3
+ currentVersion: string;
4
+ latestVersion: string;
5
+ }
6
+ /**
7
+ * Check for updates. Returns immediately with cached data if available,
8
+ * otherwise fetches from npm (with 5s timeout).
9
+ */
10
+ export declare function checkForUpdates(): UpdateInfo | null;
11
+ /**
12
+ * Format update notification message
13
+ */
14
+ export declare function formatUpdateMessage(info: UpdateInfo): string;
@@ -0,0 +1,116 @@
1
+ import { execFileSync } from 'child_process';
2
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { YEEHAW_DIR } from './paths.js';
5
+ const PACKAGE_NAME = '@colmbus72/yeehaw';
6
+ const CACHE_FILE = join(YEEHAW_DIR, '.update-check');
7
+ const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
8
+ function getCurrentVersion() {
9
+ try {
10
+ const packagePath = new URL('../../package.json', import.meta.url);
11
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
12
+ return pkg.version;
13
+ }
14
+ catch {
15
+ return '0.0.0';
16
+ }
17
+ }
18
+ function readCache() {
19
+ try {
20
+ if (!existsSync(CACHE_FILE))
21
+ return null;
22
+ const data = JSON.parse(readFileSync(CACHE_FILE, 'utf-8'));
23
+ if (Date.now() - data.checkedAt < CACHE_TTL_MS) {
24
+ return data;
25
+ }
26
+ return null; // Cache expired
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ function writeCache(latestVersion) {
33
+ try {
34
+ if (!existsSync(YEEHAW_DIR)) {
35
+ mkdirSync(YEEHAW_DIR, { recursive: true });
36
+ }
37
+ const data = {
38
+ latestVersion,
39
+ checkedAt: Date.now(),
40
+ };
41
+ writeFileSync(CACHE_FILE, JSON.stringify(data), 'utf-8');
42
+ }
43
+ catch {
44
+ // Ignore cache write errors
45
+ }
46
+ }
47
+ function fetchLatestVersion() {
48
+ try {
49
+ // Use execFileSync for safety (no shell injection possible)
50
+ const result = execFileSync('npm', ['view', PACKAGE_NAME, 'version'], {
51
+ encoding: 'utf-8',
52
+ timeout: 5000,
53
+ stdio: ['pipe', 'pipe', 'pipe'],
54
+ });
55
+ return result.trim();
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ function compareVersions(current, latest) {
62
+ const parseVersion = (v) => v.split('.').map(n => parseInt(n, 10) || 0);
63
+ const [cMajor, cMinor, cPatch] = parseVersion(current);
64
+ const [lMajor, lMinor, lPatch] = parseVersion(latest);
65
+ if (lMajor > cMajor)
66
+ return 1;
67
+ if (lMajor < cMajor)
68
+ return -1;
69
+ if (lMinor > cMinor)
70
+ return 1;
71
+ if (lMinor < cMinor)
72
+ return -1;
73
+ if (lPatch > cPatch)
74
+ return 1;
75
+ if (lPatch < cPatch)
76
+ return -1;
77
+ return 0;
78
+ }
79
+ /**
80
+ * Check for updates. Returns immediately with cached data if available,
81
+ * otherwise fetches from npm (with 5s timeout).
82
+ */
83
+ export function checkForUpdates() {
84
+ try {
85
+ const currentVersion = getCurrentVersion();
86
+ // Try cache first
87
+ const cached = readCache();
88
+ if (cached) {
89
+ return {
90
+ updateAvailable: compareVersions(currentVersion, cached.latestVersion) > 0,
91
+ currentVersion,
92
+ latestVersion: cached.latestVersion,
93
+ };
94
+ }
95
+ // Fetch from npm
96
+ const latestVersion = fetchLatestVersion();
97
+ if (!latestVersion)
98
+ return null;
99
+ // Update cache
100
+ writeCache(latestVersion);
101
+ return {
102
+ updateAvailable: compareVersions(currentVersion, latestVersion) > 0,
103
+ currentVersion,
104
+ latestVersion,
105
+ };
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }
111
+ /**
112
+ * Format update notification message
113
+ */
114
+ export function formatUpdateMessage(info) {
115
+ return `Update available: ${info.currentVersion} → ${info.latestVersion}\nRun: npm install -g ${PACKAGE_NAME}`;
116
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colmbus72/yeehaw",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Terminal dashboard for managing projects, servers, and deployments",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",