termify-agent 1.0.10 → 1.0.13
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/agent.d.ts +3 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +45 -2
- package/dist/agent.js.map +1 -1
- package/dist/daemon-client.d.ts +80 -0
- package/dist/daemon-client.d.ts.map +1 -0
- package/dist/daemon-client.js +319 -0
- package/dist/daemon-client.js.map +1 -0
- package/dist/git-service.d.ts +34 -0
- package/dist/git-service.d.ts.map +1 -0
- package/dist/git-service.js +99 -0
- package/dist/git-service.js.map +1 -0
- package/dist/pty-manager.d.ts +43 -0
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +121 -4
- package/dist/pty-manager.js.map +1 -1
- package/dist/ws-client.d.ts +42 -0
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +46 -0
- package/dist/ws-client.js.map +1 -1
- package/package.json +6 -3
- package/scripts/postinstall.js +238 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "termify-agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Termify Agent CLI - Connect your local terminal to Termify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"dev": "tsc --watch",
|
|
13
13
|
"start": "node dist/index.js",
|
|
14
14
|
"lint": "eslint src --ext .ts",
|
|
15
|
-
"clean": "rm -rf dist"
|
|
15
|
+
"clean": "rm -rf dist",
|
|
16
|
+
"postinstall": "node scripts/postinstall.js"
|
|
16
17
|
},
|
|
17
18
|
"keywords": [
|
|
18
19
|
"termify",
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
"node-pty": "^1.1.0",
|
|
30
31
|
"open": "^10.0.0",
|
|
31
32
|
"ora": "^8.0.1",
|
|
33
|
+
"simple-git": "^3.30.0",
|
|
32
34
|
"ssh2": "^1.15.0",
|
|
33
35
|
"ws": "^8.16.0"
|
|
34
36
|
},
|
|
@@ -43,6 +45,7 @@
|
|
|
43
45
|
},
|
|
44
46
|
"files": [
|
|
45
47
|
"dist",
|
|
46
|
-
"bin"
|
|
48
|
+
"bin",
|
|
49
|
+
"scripts"
|
|
47
50
|
]
|
|
48
51
|
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Termify Agent - Postinstall Script
|
|
5
|
+
*
|
|
6
|
+
* Runs automatically after `npm install` to:
|
|
7
|
+
* 1. Rebuild node-pty native module for the current platform
|
|
8
|
+
* 2. Download the termify-daemon binary for process monitoring and system stats
|
|
9
|
+
* 3. Download the stats-agent binary for detailed system monitoring (fallback)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { execSync } from 'child_process';
|
|
13
|
+
import { createWriteStream, mkdirSync, chmodSync, existsSync, unlinkSync } from 'fs';
|
|
14
|
+
import { join } from 'path';
|
|
15
|
+
import { homedir, platform, arch } from 'os';
|
|
16
|
+
import { get } from 'https';
|
|
17
|
+
|
|
18
|
+
const DOWNLOAD_BASE_URL = 'https://termify.justdiego.com/api/downloads';
|
|
19
|
+
const TERMIFY_DIR = join(homedir(), '.termify');
|
|
20
|
+
const DAEMON_PATH = join(TERMIFY_DIR, 'termify-daemon');
|
|
21
|
+
const STATS_AGENT_PATH = join(TERMIFY_DIR, 'stats-agent');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Step 1: Rebuild node-pty with improved error handling
|
|
25
|
+
*/
|
|
26
|
+
function rebuildNodePty() {
|
|
27
|
+
console.log('[termify-agent] Rebuilding node-pty for your platform...');
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// First try regular rebuild
|
|
31
|
+
execSync('npm rebuild node-pty', {
|
|
32
|
+
stdio: 'pipe',
|
|
33
|
+
timeout: 180000,
|
|
34
|
+
});
|
|
35
|
+
console.log('[termify-agent] node-pty rebuilt successfully.');
|
|
36
|
+
return true;
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.warn('[termify-agent] Warning: npm rebuild node-pty failed.');
|
|
39
|
+
console.warn('[termify-agent] Attempting to reinstall node-pty...');
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
// Try removing and reinstalling
|
|
43
|
+
execSync('rm -rf node_modules/node-pty && npm install node-pty', {
|
|
44
|
+
stdio: 'pipe',
|
|
45
|
+
timeout: 180000,
|
|
46
|
+
});
|
|
47
|
+
console.log('[termify-agent] node-pty reinstalled successfully.');
|
|
48
|
+
return true;
|
|
49
|
+
} catch (err2) {
|
|
50
|
+
console.error('[termify-agent] CRITICAL: node-pty installation failed.');
|
|
51
|
+
console.error('[termify-agent] Terminal features will NOT work.');
|
|
52
|
+
console.error('[termify-agent] Manual fix required:');
|
|
53
|
+
console.error(`[termify-agent] cd ${process.cwd()}`);
|
|
54
|
+
console.error('[termify-agent] npm rebuild node-pty');
|
|
55
|
+
console.error('[termify-agent]');
|
|
56
|
+
console.error('[termify-agent] If that fails, try:');
|
|
57
|
+
console.error('[termify-agent] rm -rf node_modules/node-pty');
|
|
58
|
+
console.error('[termify-agent] npm install node-pty');
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Step 2: Download termify-daemon binary (new efficient daemon)
|
|
66
|
+
*/
|
|
67
|
+
async function downloadDaemon() {
|
|
68
|
+
const plat = platform();
|
|
69
|
+
const ar = arch();
|
|
70
|
+
|
|
71
|
+
// Map Node.js platform/arch to our binary names
|
|
72
|
+
const platformMap = {
|
|
73
|
+
'darwin-arm64': 'darwin-arm64',
|
|
74
|
+
'darwin-x64': 'darwin-x64',
|
|
75
|
+
'linux-x64': 'linux-x64',
|
|
76
|
+
'linux-arm64': 'linux-arm64',
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const key = `${plat}-${ar}`;
|
|
80
|
+
const binaryName = platformMap[key];
|
|
81
|
+
|
|
82
|
+
if (!binaryName) {
|
|
83
|
+
console.warn(`[termify-agent] Warning: No termify-daemon binary available for ${key}.`);
|
|
84
|
+
console.warn('[termify-agent] Process monitoring will use fallback (pgrep).');
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Skip if already exists (user can delete to force re-download)
|
|
89
|
+
if (existsSync(DAEMON_PATH)) {
|
|
90
|
+
console.log('[termify-agent] termify-daemon binary already exists, skipping download.');
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log(`[termify-agent] Downloading termify-daemon for ${binaryName}...`);
|
|
95
|
+
|
|
96
|
+
// Ensure ~/.termify directory exists
|
|
97
|
+
mkdirSync(TERMIFY_DIR, { recursive: true });
|
|
98
|
+
|
|
99
|
+
const url = `${DOWNLOAD_BASE_URL}/termify-daemon/${binaryName}`;
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
await downloadFile(url, DAEMON_PATH);
|
|
103
|
+
chmodSync(DAEMON_PATH, 0o755);
|
|
104
|
+
console.log(`[termify-agent] termify-daemon installed to ${DAEMON_PATH}`);
|
|
105
|
+
return true;
|
|
106
|
+
} catch (err) {
|
|
107
|
+
console.warn(`[termify-agent] Warning: Failed to download termify-daemon: ${err.message}`);
|
|
108
|
+
console.warn('[termify-agent] Process monitoring will use fallback (pgrep).');
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Step 3: Download stats-agent binary (fallback for detailed stats)
|
|
115
|
+
*/
|
|
116
|
+
async function downloadStatsAgent() {
|
|
117
|
+
const plat = platform();
|
|
118
|
+
const ar = arch();
|
|
119
|
+
|
|
120
|
+
// Map Node.js platform/arch to our binary names
|
|
121
|
+
const platformMap = {
|
|
122
|
+
'darwin-arm64': 'darwin-arm64',
|
|
123
|
+
'darwin-x64': 'darwin-x64',
|
|
124
|
+
'linux-x64': 'linux-x64',
|
|
125
|
+
'linux-arm64': 'linux-arm64',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const key = `${plat}-${ar}`;
|
|
129
|
+
const binaryName = platformMap[key];
|
|
130
|
+
|
|
131
|
+
if (!binaryName) {
|
|
132
|
+
console.warn(`[termify-agent] Warning: No stats-agent binary available for ${key}.`);
|
|
133
|
+
console.warn('[termify-agent] Detailed system stats collection will be disabled.');
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Skip if already exists
|
|
138
|
+
if (existsSync(STATS_AGENT_PATH)) {
|
|
139
|
+
console.log('[termify-agent] stats-agent binary already exists, skipping download.');
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.log(`[termify-agent] Downloading stats-agent for ${binaryName}...`);
|
|
144
|
+
|
|
145
|
+
// Ensure ~/.termify directory exists
|
|
146
|
+
mkdirSync(TERMIFY_DIR, { recursive: true });
|
|
147
|
+
|
|
148
|
+
const url = `${DOWNLOAD_BASE_URL}/stats-agent/${binaryName}`;
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
await downloadFile(url, STATS_AGENT_PATH);
|
|
152
|
+
chmodSync(STATS_AGENT_PATH, 0o755);
|
|
153
|
+
console.log(`[termify-agent] stats-agent installed to ${STATS_AGENT_PATH}`);
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.warn(`[termify-agent] Warning: Failed to download stats-agent: ${err.message}`);
|
|
156
|
+
console.warn('[termify-agent] Detailed system stats collection will be disabled.');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Download a file following redirects (up to 5)
|
|
162
|
+
*/
|
|
163
|
+
function downloadFile(url, dest, redirects = 0) {
|
|
164
|
+
return new Promise((resolve, reject) => {
|
|
165
|
+
if (redirects > 5) {
|
|
166
|
+
return reject(new Error('Too many redirects'));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const request = get(url, (response) => {
|
|
170
|
+
// Handle redirects
|
|
171
|
+
if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
|
|
172
|
+
return downloadFile(response.headers.location, dest, redirects + 1)
|
|
173
|
+
.then(resolve)
|
|
174
|
+
.catch(reject);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (response.statusCode !== 200) {
|
|
178
|
+
return reject(new Error(`HTTP ${response.statusCode}`));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const file = createWriteStream(dest);
|
|
182
|
+
response.pipe(file);
|
|
183
|
+
file.on('finish', () => {
|
|
184
|
+
file.close();
|
|
185
|
+
resolve();
|
|
186
|
+
});
|
|
187
|
+
file.on('error', (err) => {
|
|
188
|
+
file.close();
|
|
189
|
+
// Clean up partial download
|
|
190
|
+
try { unlinkSync(dest); } catch {}
|
|
191
|
+
reject(err);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
request.on('error', reject);
|
|
196
|
+
request.setTimeout(60000, () => {
|
|
197
|
+
request.destroy();
|
|
198
|
+
reject(new Error('Download timed out'));
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Main
|
|
205
|
+
*/
|
|
206
|
+
async function main() {
|
|
207
|
+
console.log('[termify-agent] Running postinstall...');
|
|
208
|
+
console.log(`[termify-agent] Platform: ${platform()}-${arch()}`);
|
|
209
|
+
|
|
210
|
+
// Step 1: Rebuild node-pty (critical for terminal functionality)
|
|
211
|
+
const nodePtyOk = rebuildNodePty();
|
|
212
|
+
if (!nodePtyOk) {
|
|
213
|
+
console.error('[termify-agent] WARNING: Terminal features may not work until node-pty is fixed.');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Step 2: Download termify-daemon (efficient process monitoring)
|
|
217
|
+
try {
|
|
218
|
+
await downloadDaemon();
|
|
219
|
+
} catch (err) {
|
|
220
|
+
console.warn(`[termify-agent] Warning: ${err.message}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Step 3: Download stats-agent (fallback for detailed stats)
|
|
224
|
+
try {
|
|
225
|
+
await downloadStatsAgent();
|
|
226
|
+
} catch (err) {
|
|
227
|
+
// Non-fatal - stats is optional
|
|
228
|
+
console.warn(`[termify-agent] Warning: ${err.message}`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
console.log('[termify-agent] Postinstall complete.');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
main().catch((err) => {
|
|
235
|
+
console.warn(`[termify-agent] Postinstall warning: ${err.message}`);
|
|
236
|
+
// Never fail the install - postinstall errors should be warnings only
|
|
237
|
+
process.exit(0);
|
|
238
|
+
});
|