thinknagent 0.1.12 → 0.1.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/Readme.md CHANGED
@@ -45,6 +45,7 @@ chmod +x (which thinknagent)
45
45
  | `--room <roomId>` | ✅ | Room ID to connect to |
46
46
  | `--gpu` | ❌ | Enable GPU metrics (requires nvidia-smi) |
47
47
  | `--logs <paths>` | ❌ | Comma-separated log file paths to stream |
48
+ | `--app-path <path>` | ❌ | Path to the deployed application folder (to track and display version) |
48
49
 
49
50
  ---
50
51
 
@@ -78,14 +79,15 @@ thinknagent init \
78
79
  --logs <YOUR_PM2_LOG_FILE>
79
80
  ```
80
81
 
81
- **With GPU metrics:**
82
+ **With GPU metrics & application version tracking:**
82
83
  ```bash
83
84
  thinknagent init \
84
85
  --server YOUR_APP_SERVER \
85
86
  --name my-server \
86
87
  --room <roomId> \
87
88
  --gpu \
88
- --logs <YOUR_SYS_LOG_FILE>
89
+ --logs <YOUR_SYS_LOG_FILE> \
90
+ --app-path /var/www/my-node-app
89
91
  ```
90
92
 
91
93
  Get your `roomId` from the room URL:
@@ -98,24 +100,40 @@ thinknagent start
98
100
  ```
99
101
 
100
102
  Output:
103
+ ```
101
104
  Starting thinknagent — my-server
102
105
  Status: PENDING — waiting for Owner approval
103
106
  [agent] Connecting to https://thinkncollab.com...
104
107
  [thinknagent] Registered as <agentId> — waiting for Owner approval...
108
+ ```
105
109
 
106
110
  ### Step 3 — Approve in Browser
107
111
 
108
- Go to your room's DevOps Wall:
109
- https://thinkncollab.com/devops/<roomId>/devops
110
-
111
- Click **Approve** on the pending agent in the sidebar.
112
+ 1. Go to your room's DevOps Wall:
113
+ `https://thinkncollab.com/devops/<roomId>/devops`
114
+ 2. Click **Approve** on the pending agent in the sidebar.
112
115
 
113
116
  Once approved:
117
+ ```
114
118
  [thinknagent] Approved! Role: monitor | Room: <roomId>
115
119
  [agent] Active. Role: monitor | Room: <roomId>
116
120
  [metrics] Poller started
117
121
  [logs] Watching 2 file(s)
118
122
  [shell] Bridge ready
123
+ ```
124
+
125
+ ### Step 4 — Run with PM2 (Keep Alive)
126
+
127
+ To run the agent in the background so that all features (metrics, logs, shell) stay permanently active and accessible after you disconnect your terminal session:
128
+
129
+ ```bash
130
+ # Start the agent using PM2
131
+ pm2 start thinknagent --name "thinknagent_logs" -- start
132
+
133
+ # Save PM2 process list and configure startup
134
+ pm2 save
135
+ pm2 startup
136
+ ```
119
137
 
120
138
  ---
121
139
 
@@ -24,6 +24,7 @@ program
24
24
  .option('--room <roomId>', 'Room ID to connect to')
25
25
  .option('--gpu', 'Enable GPU metrics (requires nvidia-smi)')
26
26
  .option('--logs <paths>', 'Comma-separated log file paths to stream')
27
+ .option('--app-path <path>', 'Path to the deployed application folder (to track version)')
27
28
  .action(async (opts) => {
28
29
  const existing = store.get('agentToken');
29
30
  if (existing) {
@@ -40,6 +41,7 @@ program
40
41
  gpu: !!opts.gpu,
41
42
  logs: opts.logs ? opts.logs.split(',').map(s => s.trim()) : [],
42
43
  roomId: opts.room,
44
+ appPath: opts.appPath || null,
43
45
  alerts: [
44
46
  // sensible defaults — Owner can edit in browser
45
47
  { id: 'cpu-high', metric: 'cpu.usage', op: 'gt', value: 85, for: 60, severity: 'warning' },
@@ -58,6 +60,7 @@ program
58
60
  console.log(` Agent ID: ${chalk.white(agentId)}`);
59
61
  console.log(` GPU : ${cfg.gpu ? chalk.green('enabled') : chalk.gray('disabled')}`);
60
62
  console.log(` Logs : ${cfg.logs.length ? chalk.white(cfg.logs.join(', ')) : chalk.gray('none')}`);
63
+ console.log(` App Path: ${cfg.appPath ? chalk.white(cfg.appPath) : chalk.gray('none')}`);
61
64
  console.log(chalk.gray(' ─────────────────────────────────────────'));
62
65
  console.log(chalk.yellow('\n Next step:'));
63
66
  console.log(' 1. Run: ' + chalk.cyan('thinknagent start'));
@@ -109,6 +112,7 @@ program
109
112
  console.log(` Status : ${cfg.agentToken ? chalk.green('APPROVED') : chalk.yellow('PENDING')}`);
110
113
  console.log(` GPU : ${cfg.gpu ? chalk.green('enabled') : chalk.gray('disabled')}`);
111
114
  console.log(` Logs : ${(cfg.logs||[]).length ? cfg.logs.join(', ') : chalk.gray('none')}`);
115
+ console.log(` App Path: ${cfg.appPath ? chalk.white(cfg.appPath) : chalk.gray('none')}`);
112
116
  console.log(` Alerts : ${(cfg.alerts||[]).length} rule(s)`);
113
117
  console.log(chalk.gray(' ────────────────────────────────\n'));
114
118
  });
package/lib/connect.js CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  const { io } = require('socket.io-client');
4
4
  const store = require('./store');
5
+ const { execSync } = require('child_process');
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ function getDeployedAppVersion(appPath) {
10
+ try {
11
+ const resolvedPath = path.resolve(appPath || process.cwd());
12
+ let pkgVersion = '';
13
+ let gitCommit = '';
14
+
15
+ const pkgJsonPath = path.join(resolvedPath, 'package.json');
16
+ if (fs.existsSync(pkgJsonPath)) {
17
+ try {
18
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
19
+ pkgVersion = pkg.version || '';
20
+ } catch (e) {}
21
+ }
22
+
23
+ try {
24
+ gitCommit = execSync('git log -n 1 --format="%h - %s" --no-color', {
25
+ cwd: resolvedPath,
26
+ stdio: ['ignore', 'pipe', 'ignore'],
27
+ timeout: 2000,
28
+ encoding: 'utf8'
29
+ }).trim();
30
+ } catch (e) {}
31
+
32
+ if (pkgVersion && gitCommit) {
33
+ return `v${pkgVersion} (${gitCommit})`;
34
+ } else if (pkgVersion) {
35
+ return `v${pkgVersion}`;
36
+ } else if (gitCommit) {
37
+ return gitCommit;
38
+ }
39
+ return 'unknown';
40
+ } catch (err) {
41
+ return 'unknown';
42
+ }
43
+ }
5
44
 
6
45
  const NAMESPACE = '/devops';
7
46
  const RECONNECT_DELAY = 5000;
@@ -34,18 +73,19 @@ class Connection {
34
73
  reconnection: true,
35
74
  reconnectionDelay: RECONNECT_DELAY,
36
75
  reconnectionAttempts: Infinity,
37
- auth: (cb) => {
38
- const freshCfg = store.read();
39
- console.log('[debug] Reconnecting with token:', !!freshCfg.agentToken, 'agentId:', freshCfg.agentId);
40
- cb({
41
- agentId: freshCfg.agentId,
42
- agentToken: freshCfg.agentToken || null,
43
- name: freshCfg.name,
44
- hostname: require('os').hostname(),
45
- version: require('../package.json').version,
46
- roomId: freshCfg.roomId || null,
47
- });
48
- }
76
+ auth: (cb) => {
77
+ const freshCfg = store.read();
78
+ console.log('[debug] Reconnecting with token:', !!freshCfg.agentToken, 'agentId:', freshCfg.agentId);
79
+ cb({
80
+ agentId: freshCfg.agentId,
81
+ agentToken: freshCfg.agentToken || null,
82
+ name: freshCfg.name,
83
+ hostname: require('os').hostname(),
84
+ version: require('../package.json').version,
85
+ roomId: freshCfg.roomId || null,
86
+ appVersion: getDeployedAppVersion(freshCfg.appPath),
87
+ });
88
+ }
49
89
  });
50
90
 
51
91
  this._bind();
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "thinknagent",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "ThinkNCollab server agent — metrics, logs, alerts, shell bridge",
5
5
  "main": "lib/agent.js",
6
- "author": "ThinkNCollab Team <team@thinkncollab.com>",
6
+ "author": "ThinkNCollab Team <raman@thinkncollab.com>",
7
7
  "bin": {
8
- "thinknagent": "./bin/thinknagent.js"
8
+ "thinknagent": "bin/thinknagent.js"
9
9
  },
10
10
  "scripts": {
11
11
  "start": "node bin/thinknagent.js start",
@@ -25,6 +25,11 @@
25
25
  "engines": {
26
26
  "node": ">=18.0.0"
27
27
  },
28
- "keywords": ["thinkncollab", "devops", "monitoring", "agent"],
28
+ "keywords": [
29
+ "thinkncollab",
30
+ "devops",
31
+ "monitoring",
32
+ "agent"
33
+ ],
29
34
  "license": "MIT"
30
35
  }