gsd-agent 1.0.0 → 1.0.1
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 +118 -77
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -12,31 +12,46 @@
|
|
|
12
12
|
* gsd-agent version - Show version
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
15
|
+
import { execSync, spawn } from 'child_process';
|
|
16
|
+
import { readFile } from 'fs/promises';
|
|
17
|
+
import { join, dirname } from 'path';
|
|
18
|
+
import { fileURLToPath } from 'url';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = dirname(__filename);
|
|
22
|
+
|
|
23
|
+
const AGENT_DIST = join(__dirname, '..', 'dist', 'index.js');
|
|
24
|
+
const CREDENTIALS_PATH = join(process.env.HOME || '', '.gsd-agent', 'credentials.json');
|
|
25
|
+
const LOG_FILE = join(process.env.HOME || '', '.gsd-agent', 'logs', 'agent.log');
|
|
23
26
|
const VERSION = '1.0.0';
|
|
24
27
|
|
|
25
28
|
/**
|
|
26
29
|
* Check if agent is authenticated
|
|
27
30
|
*/
|
|
28
|
-
function isAuthenticated() {
|
|
31
|
+
async function isAuthenticated() {
|
|
29
32
|
try {
|
|
30
|
-
if (!
|
|
33
|
+
if (!await fileExists(CREDENTIALS_PATH)) {
|
|
31
34
|
return false;
|
|
32
35
|
}
|
|
33
|
-
const credentials = JSON.parse(
|
|
36
|
+
const credentials = JSON.parse(await readFile(CREDENTIALS_PATH, 'utf-8'));
|
|
34
37
|
return !!(credentials.access_token && credentials.user_id);
|
|
35
38
|
} catch {
|
|
36
39
|
return false;
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Check if file exists
|
|
45
|
+
*/
|
|
46
|
+
async function fileExists(path) {
|
|
47
|
+
try {
|
|
48
|
+
await readFile(path);
|
|
49
|
+
return true;
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
40
55
|
/**
|
|
41
56
|
* Show help message
|
|
42
57
|
*/
|
|
@@ -63,7 +78,7 @@ Examples:
|
|
|
63
78
|
gsd-agent logs --lines 50 # Show last 50 log lines
|
|
64
79
|
|
|
65
80
|
Documentation:
|
|
66
|
-
https://gsd
|
|
81
|
+
https://gsd.fahad.ink/docs/agent-setup
|
|
67
82
|
`);
|
|
68
83
|
}
|
|
69
84
|
|
|
@@ -97,55 +112,69 @@ async function runAuth() {
|
|
|
97
112
|
* Start the agent daemon
|
|
98
113
|
*/
|
|
99
114
|
function startAgent() {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
console.log('Starting GSD Agent daemon...\n');
|
|
106
|
-
|
|
107
|
-
if (!fs.existsSync(AGENT_DIST)) {
|
|
108
|
-
console.log('Agent not built. Running build...\n');
|
|
109
|
-
try {
|
|
110
|
-
execSync('npm run build', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.error('Build failed. Please run: npm run build\n');
|
|
115
|
+
// Check authentication asynchronously
|
|
116
|
+
isAuthenticated().then(isAuth => {
|
|
117
|
+
if (!isAuth) {
|
|
118
|
+
console.log('Not authenticated. Please run: gsd-agent auth\n');
|
|
113
119
|
process.exit(1);
|
|
114
120
|
}
|
|
115
|
-
}
|
|
116
121
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
console.log('Starting GSD Agent daemon...\n');
|
|
123
|
+
|
|
124
|
+
// Check if agent is built
|
|
125
|
+
fileExists(AGENT_DIST).then(agentBuilt => {
|
|
126
|
+
if (!agentBuilt) {
|
|
127
|
+
console.log('Agent not built. Running build...\n');
|
|
128
|
+
try {
|
|
129
|
+
execSync('npm run build', { stdio: 'inherit', cwd: join(__dirname, '..') });
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error('Build failed. Please run: npm run build\n');
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
122
135
|
|
|
123
|
-
|
|
124
|
-
|
|
136
|
+
// Start the agent
|
|
137
|
+
const agent = spawn('node', [AGENT_DIST], {
|
|
138
|
+
stdio: 'inherit',
|
|
139
|
+
env: { ...process.env }
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
agent.on('error', (error) => {
|
|
143
|
+
console.error('Failed to start agent:', error.message);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
agent.on('exit', (code) => {
|
|
148
|
+
if (code !== 0) {
|
|
149
|
+
console.error(`Agent exited with code ${code}`);
|
|
150
|
+
process.exit(code);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}).catch(err => {
|
|
155
|
+
console.error('Error checking authentication:', err.message);
|
|
125
156
|
process.exit(1);
|
|
126
157
|
});
|
|
127
|
-
|
|
128
|
-
agent.on('exit', (code) => {
|
|
129
|
-
if (code !== 0) {
|
|
130
|
-
console.error(`Agent exited with code ${code}`);
|
|
131
|
-
process.exit(code);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
158
|
}
|
|
135
159
|
|
|
136
160
|
/**
|
|
137
161
|
* Show agent status
|
|
138
162
|
*/
|
|
139
|
-
function showStatus() {
|
|
163
|
+
async function showStatus() {
|
|
140
164
|
console.log('GSD Agent Status\n');
|
|
141
165
|
console.log('================\n');
|
|
142
166
|
|
|
143
167
|
// Check authentication
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
168
|
+
const auth = await isAuthenticated();
|
|
169
|
+
if (auth) {
|
|
170
|
+
try {
|
|
171
|
+
const credentials = JSON.parse(await readFile(CREDENTIALS_PATH, 'utf-8'));
|
|
172
|
+
console.log('Authentication: ✓ Connected');
|
|
173
|
+
console.log(`User ID: ${credentials.user_id}`);
|
|
174
|
+
console.log(`Token expires: ${credentials.expires_at}`);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.log('Authentication: ✗ Error reading credentials');
|
|
177
|
+
}
|
|
149
178
|
} else {
|
|
150
179
|
console.log('Authentication: ✗ Not authenticated');
|
|
151
180
|
console.log('Run: gsd-agent auth\n');
|
|
@@ -158,7 +187,7 @@ function showStatus() {
|
|
|
158
187
|
const result = execSync('pgrep -f "gsd-agent" || true', { encoding: 'utf-8' });
|
|
159
188
|
if (result.trim()) {
|
|
160
189
|
console.log('Agent Process: ✓ Running');
|
|
161
|
-
console.log(`PID: ${result.trim().split('\n').join(', ')}`);
|
|
190
|
+
console.log(`PID: ${result.trim().split('\n').filter(Boolean).join(', ')}`);
|
|
162
191
|
} else {
|
|
163
192
|
console.log('Agent Process: ✗ Not running');
|
|
164
193
|
console.log('Run: gsd-agent start\n');
|
|
@@ -171,11 +200,17 @@ function showStatus() {
|
|
|
171
200
|
console.log('');
|
|
172
201
|
|
|
173
202
|
// Check log file
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
203
|
+
if (await fileExists(LOG_FILE)) {
|
|
204
|
+
try {
|
|
205
|
+
const { stat } = await import('fs/promises');
|
|
206
|
+
const stats = await stat(LOG_FILE);
|
|
207
|
+
console.log(`Log File: ${LOG_FILE}`);
|
|
208
|
+
console.log(`Last modified: ${stats.mtime.toISOString()}`);
|
|
209
|
+
console.log('View logs: gsd-agent logs\n');
|
|
210
|
+
} catch (error) {
|
|
211
|
+
console.log(`Log File: ${LOG_FILE}`);
|
|
212
|
+
console.log('Could not get stats for log file\n');
|
|
213
|
+
}
|
|
179
214
|
}
|
|
180
215
|
|
|
181
216
|
console.log('================\n');
|
|
@@ -184,7 +219,7 @@ function showStatus() {
|
|
|
184
219
|
/**
|
|
185
220
|
* Disconnect and clear credentials
|
|
186
221
|
*/
|
|
187
|
-
function disconnect() {
|
|
222
|
+
async function disconnect() {
|
|
188
223
|
console.log('Disconnecting GSD Agent...\n');
|
|
189
224
|
|
|
190
225
|
try {
|
|
@@ -197,8 +232,9 @@ function disconnect() {
|
|
|
197
232
|
}
|
|
198
233
|
|
|
199
234
|
// Clear credentials
|
|
200
|
-
if (
|
|
201
|
-
fs
|
|
235
|
+
if (await fileExists(CREDENTIALS_PATH)) {
|
|
236
|
+
const { unlink } = await import('fs/promises');
|
|
237
|
+
await unlink(CREDENTIALS_PATH);
|
|
202
238
|
console.log('✓ Credentials cleared');
|
|
203
239
|
} else {
|
|
204
240
|
console.log('✓ No credentials found');
|
|
@@ -217,29 +253,34 @@ function disconnect() {
|
|
|
217
253
|
function showLogs(options = {}) {
|
|
218
254
|
const lines = options.lines || 50;
|
|
219
255
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
console.log(`Tailing agent logs (last ${lines} lines)...\n`);
|
|
227
|
-
console.log('Press Ctrl+C to stop\n');
|
|
256
|
+
fileExists(LOG_FILE).then(logExists => {
|
|
257
|
+
if (!logExists) {
|
|
258
|
+
console.log('No log file found. Agent may not have been started yet.\n');
|
|
259
|
+
console.log(`Expected location: ${LOG_FILE}\n`);
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
228
262
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const tail = spawn('tail', ['-f', '-n', String(lines), LOG_FILE], {
|
|
232
|
-
stdio: 'inherit'
|
|
233
|
-
});
|
|
263
|
+
console.log(`Tailing agent logs (last ${lines} lines)...\n`);
|
|
264
|
+
console.log('Press Ctrl+C to stop\n');
|
|
234
265
|
|
|
235
|
-
|
|
236
|
-
|
|
266
|
+
try {
|
|
267
|
+
// Use tail -f to follow logs
|
|
268
|
+
const tail = spawn('tail', ['-f', '-n', String(lines), LOG_FILE], {
|
|
269
|
+
stdio: 'inherit'
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
tail.on('error', (error) => {
|
|
273
|
+
console.error('Failed to tail logs:', error.message);
|
|
274
|
+
process.exit(1);
|
|
275
|
+
});
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.error('Error:', error.message);
|
|
237
278
|
process.exit(1);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
console.error('Error:',
|
|
279
|
+
}
|
|
280
|
+
}).catch(err => {
|
|
281
|
+
console.error('Error checking log file:', err.message);
|
|
241
282
|
process.exit(1);
|
|
242
|
-
}
|
|
283
|
+
});
|
|
243
284
|
}
|
|
244
285
|
|
|
245
286
|
/**
|
|
@@ -279,10 +320,10 @@ async function main() {
|
|
|
279
320
|
startAgent();
|
|
280
321
|
break;
|
|
281
322
|
case 'status':
|
|
282
|
-
showStatus();
|
|
323
|
+
await showStatus();
|
|
283
324
|
break;
|
|
284
325
|
case 'disconnect':
|
|
285
|
-
disconnect();
|
|
326
|
+
await disconnect();
|
|
286
327
|
break;
|
|
287
328
|
case 'logs':
|
|
288
329
|
showLogs(options);
|
|
@@ -310,4 +351,4 @@ async function main() {
|
|
|
310
351
|
main().catch((error) => {
|
|
311
352
|
console.error('Fatal error:', error.message);
|
|
312
353
|
process.exit(1);
|
|
313
|
-
});
|
|
354
|
+
});
|
package/package.json
CHANGED