thinknagent 0.1.33 → 0.1.34

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/lib/alerts.js CHANGED
@@ -15,14 +15,21 @@
15
15
  * "for" = seconds the condition must persist before firing (0 = fire immediately)
16
16
  */
17
17
 
18
+ const DEFAULT_ALERT_RULES = [
19
+ { id: 'cpu-high', metric: 'cpu.usage', op: 'gt', value: 85, for: 30, severity: 'warning' },
20
+ { id: 'cpu-crit', metric: 'cpu.usage', op: 'gt', value: 95, for: 15, severity: 'critical' },
21
+ { id: 'mem-high', metric: 'memory.usedPct', op: 'gt', value: 90, for: 30, severity: 'warning' },
22
+ { id: 'disk-root', metric: 'disk./', op: 'gt', value: 90, for: 0, severity: 'critical' },
23
+ ];
24
+
18
25
  class AlertEngine {
19
26
  constructor({ connection, rules = [] }) {
20
27
  this.conn = connection;
21
- this.rules = rules;
28
+ this.rules = (rules && rules.length > 0) ? rules : DEFAULT_ALERT_RULES;
22
29
 
23
30
  // per-rule state: { firstTriggeredAt, fired }
24
31
  this._state = {};
25
- for (const r of rules) {
32
+ for (const r of this.rules) {
26
33
  this._state[r.id] = { firstTriggeredAt: null, fired: false };
27
34
  }
28
35
  }
package/lib/metrics.js CHANGED
@@ -236,13 +236,26 @@ class MetricsPoller {
236
236
  // pehle alert engine aur history ko raw metrics pass karo — 24/7 Edge evaluation
237
237
  this.onMetricsEmit?.(payload);
238
238
 
239
+ // Military-grade AES-256-GCM End-to-End Encryption (E2EE)
239
240
  const store = require('./store');
241
+ const { encryptE2EE } = require('./e2ee');
242
+ const roomId = this.conn?.roomId || store.get('roomId');
240
243
  const agentId = this.conn?.agentId || store.get('agentId');
241
244
 
242
- this.conn.emit('agent:metrics', {
243
- agentId,
244
- ...payload
245
- });
245
+ if (roomId) {
246
+ const encrypted = encryptE2EE(payload, roomId);
247
+ this.conn.emit('agent:metrics', {
248
+ agentId,
249
+ ts: payload.ts,
250
+ encrypted,
251
+ e2ee: true
252
+ });
253
+ } else {
254
+ this.conn.emit('agent:metrics', {
255
+ agentId,
256
+ ...payload
257
+ });
258
+ }
246
259
 
247
260
  } catch (err) {
248
261
  console.error('[metrics] Poll error:', err.message);
package/lib/shell.js CHANGED
@@ -98,7 +98,7 @@ class ShellBridge {
98
98
  env: safeEnv,
99
99
  });
100
100
 
101
- proc.onData(data => s.emit('shell:data', { sessionId, data }));
101
+ proc.onData(data => this._sendData(s, sessionId, data));
102
102
  proc.onExit(({ exitCode }) => {
103
103
  s.emit('shell:exit', { sessionId, exitCode });
104
104
  this._sessions.delete(sessionId);
@@ -119,12 +119,12 @@ class ShellBridge {
119
119
  stdio: ['pipe', 'pipe', 'pipe']
120
120
  });
121
121
 
122
- proc.stdout.on('data', data => s.emit('shell:data', { sessionId, data: data.toString() }));
122
+ proc.stdout.on('data', data => this._sendData(s, sessionId, data.toString()));
123
123
  proc.stderr.on('data', data => {
124
124
  const clean = data.toString()
125
125
  .replace(/^bash: cannot set terminal process group.*?\n/gm, '')
126
126
  .replace(/^bash: no job control in this shell.*?\n/gm, '');
127
- if (clean) s.emit('shell:data', { sessionId, data: clean });
127
+ if (clean) this._sendData(s, sessionId, clean);
128
128
  });
129
129
  proc.on('exit', exitCode => {
130
130
  s.emit('shell:exit', { sessionId, exitCode: exitCode || 0 });
@@ -150,13 +150,13 @@ class ShellBridge {
150
150
  stdio: ['pipe', 'pipe', 'pipe']
151
151
  });
152
152
 
153
- proc.stdout.on('data', data => s.emit('shell:data', { sessionId, data: data.toString() }));
153
+ proc.stdout.on('data', data => this._sendData(s, sessionId, data.toString()));
154
154
  proc.stderr.on('data', data => {
155
155
  // Filter out terminal ioctl startup noise on non-tty pipes
156
156
  const clean = data.toString()
157
157
  .replace(/^bash: cannot set terminal process group.*?\n/gm, '')
158
158
  .replace(/^bash: no job control in this shell.*?\n/gm, '');
159
- if (clean) s.emit('shell:data', { sessionId, data: clean });
159
+ if (clean) this._sendData(s, sessionId, clean);
160
160
  });
161
161
  proc.on('exit', exitCode => {
162
162
  s.emit('shell:exit', { sessionId, exitCode: exitCode || 0 });
@@ -175,10 +175,19 @@ class ShellBridge {
175
175
  }
176
176
  });
177
177
 
178
- s.on('shell:input', ({ sessionId, data }) => {
178
+ s.on('shell:input', ({ sessionId, data, e2ee }) => {
179
179
  const proc = this._sessions.get(sessionId);
180
180
  if (!proc) return;
181
- proc.write(data);
181
+ let text = data;
182
+ if (e2ee || (typeof data === 'string' && data.startsWith('e2ee:'))) {
183
+ const store = require('./store');
184
+ const { decryptE2EE } = require('./e2ee');
185
+ const roomId = this.conn?.roomId || store.get('roomId');
186
+ if (roomId) {
187
+ text = decryptE2EE(data, roomId);
188
+ }
189
+ }
190
+ proc.write(text);
182
191
  });
183
192
 
184
193
  s.on('shell:resize', ({ sessionId, cols, rows }) => {
@@ -201,6 +210,19 @@ class ShellBridge {
201
210
  }
202
211
  }
203
212
 
213
+ _sendData(s, sessionId, rawChunk) {
214
+ if (!rawChunk) return;
215
+ const store = require('./store');
216
+ const { encryptE2EE } = require('./e2ee');
217
+ const roomId = this.conn?.roomId || store.get('roomId');
218
+ if (roomId) {
219
+ const encrypted = encryptE2EE(rawChunk, roomId);
220
+ s.emit('shell:data', { sessionId, data: encrypted, e2ee: true });
221
+ } else {
222
+ s.emit('shell:data', { sessionId, data: rawChunk, e2ee: false });
223
+ }
224
+ }
225
+
204
226
  killAll() {
205
227
  for (const [id] of this._sessions) this._killSession(id);
206
228
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thinknagent",
3
- "version": "0.1.33",
3
+ "version": "0.1.34",
4
4
  "description": "ThinkNCollab server agent & MCP server — metrics, logs, alerts, shell bridge, AI planning",
5
5
  "main": "lib/agent.js",
6
6
  "author": "ThinkNCollab Team <raman@thinkncollab.com>",