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.
Files changed (2) hide show
  1. package/bin/cli.js +118 -77
  2. 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
- const { execSync, spawn } = require('child_process');
16
- const path = require('path');
17
- const fs = require('fs');
18
- const os = require('os');
19
-
20
- const AGENT_DIST = path.join(__dirname, '..', 'dist', 'index.js');
21
- const CREDENTIALS_PATH = path.join(os.homedir(), '.gsd-agent', 'credentials.json');
22
- const LOG_FILE = path.join(os.homedir(), '.gsd-agent', 'logs', 'agent.log');
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 (!fs.existsSync(CREDENTIALS_PATH)) {
33
+ if (!await fileExists(CREDENTIALS_PATH)) {
31
34
  return false;
32
35
  }
33
- const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, 'utf-8'));
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-webui-domain.com/docs/agent-setup
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
- if (!isAuthenticated()) {
101
- console.log('Not authenticated. Please run: gsd-agent auth\n');
102
- process.exit(1);
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
- // Start the agent
118
- const agent = spawn('node', [AGENT_DIST], {
119
- stdio: 'inherit',
120
- env: { ...process.env }
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
- agent.on('error', (error) => {
124
- console.error('Failed to start agent:', error.message);
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
- if (isAuthenticated()) {
145
- const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, 'utf-8'));
146
- console.log('Authentication: ✓ Connected');
147
- console.log(`User ID: ${credentials.user_id}`);
148
- console.log(`Token expires: ${credentials.expires_at}`);
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 (fs.existsSync(LOG_FILE)) {
175
- const stats = fs.statSync(LOG_FILE);
176
- console.log(`Log File: ${LOG_FILE}`);
177
- console.log(`Last modified: ${stats.mtime.toISOString()}`);
178
- console.log('View logs: gsd-agent logs\n');
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 (fs.existsSync(CREDENTIALS_PATH)) {
201
- fs.unlinkSync(CREDENTIALS_PATH);
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
- if (!fs.existsSync(LOG_FILE)) {
221
- console.log('No log file found. Agent may not have been started yet.\n');
222
- console.log(`Expected location: ${LOG_FILE}\n`);
223
- process.exit(1);
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
- try {
230
- // Use tail -f to follow logs
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
- tail.on('error', (error) => {
236
- console.error('Failed to tail logs:', error.message);
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
- } catch (error) {
240
- console.error('Error:', error.message);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-agent",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Local filesystem sync daemon for GSD projects - Connect your local .planning/ directories to the GSD cloud",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",