helixmind 0.2.0 → 0.2.2
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.
Potentially problematic release.
This version of helixmind might be problematic. Click here for more details.
- package/README.md +47 -0
- package/dist/cli/agent/autonomous.d.ts +14 -0
- package/dist/cli/agent/autonomous.d.ts.map +1 -1
- package/dist/cli/agent/autonomous.js +22 -0
- package/dist/cli/agent/autonomous.js.map +1 -1
- package/dist/cli/agent/monitor/alerter.d.ts +29 -0
- package/dist/cli/agent/monitor/alerter.d.ts.map +1 -0
- package/dist/cli/agent/monitor/alerter.js +80 -0
- package/dist/cli/agent/monitor/alerter.js.map +1 -0
- package/dist/cli/agent/monitor/baseline.d.ts +14 -0
- package/dist/cli/agent/monitor/baseline.d.ts.map +1 -0
- package/dist/cli/agent/monitor/baseline.js +157 -0
- package/dist/cli/agent/monitor/baseline.js.map +1 -0
- package/dist/cli/agent/monitor/prompts.d.ts +9 -0
- package/dist/cli/agent/monitor/prompts.d.ts.map +1 -0
- package/dist/cli/agent/monitor/prompts.js +103 -0
- package/dist/cli/agent/monitor/prompts.js.map +1 -0
- package/dist/cli/agent/monitor/responder.d.ts +12 -0
- package/dist/cli/agent/monitor/responder.d.ts.map +1 -0
- package/dist/cli/agent/monitor/responder.js +59 -0
- package/dist/cli/agent/monitor/responder.js.map +1 -0
- package/dist/cli/agent/monitor/scanner.d.ts +18 -0
- package/dist/cli/agent/monitor/scanner.d.ts.map +1 -0
- package/dist/cli/agent/monitor/scanner.js +81 -0
- package/dist/cli/agent/monitor/scanner.js.map +1 -0
- package/dist/cli/agent/monitor/types.d.ts +119 -0
- package/dist/cli/agent/monitor/types.d.ts.map +1 -0
- package/dist/cli/agent/monitor/types.js +5 -0
- package/dist/cli/agent/monitor/types.js.map +1 -0
- package/dist/cli/agent/monitor/watcher.d.ts +4 -0
- package/dist/cli/agent/monitor/watcher.d.ts.map +1 -0
- package/dist/cli/agent/monitor/watcher.js +214 -0
- package/dist/cli/agent/monitor/watcher.js.map +1 -0
- package/dist/cli/brain/control-protocol.d.ts +47 -1
- package/dist/cli/brain/control-protocol.d.ts.map +1 -1
- package/dist/cli/brain/control-protocol.js.map +1 -1
- package/dist/cli/brain/generator.d.ts +14 -0
- package/dist/cli/brain/generator.d.ts.map +1 -1
- package/dist/cli/brain/generator.js +40 -0
- package/dist/cli/brain/generator.js.map +1 -1
- package/dist/cli/checkpoints/browser.d.ts +3 -4
- package/dist/cli/checkpoints/browser.d.ts.map +1 -1
- package/dist/cli/checkpoints/browser.js +162 -135
- package/dist/cli/checkpoints/browser.js.map +1 -1
- package/dist/cli/checkpoints/store.js +1 -1
- package/dist/cli/checkpoints/store.js.map +1 -1
- package/dist/cli/commands/chat.d.ts.map +1 -1
- package/dist/cli/commands/chat.js +292 -34
- package/dist/cli/commands/chat.js.map +1 -1
- package/dist/cli/ui/activity.d.ts.map +1 -1
- package/dist/cli/ui/activity.js +11 -5
- package/dist/cli/ui/activity.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitor System — Executes defense actions (defensive/active mode only).
|
|
3
|
+
*/
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
/**
|
|
6
|
+
* Execute a defense action using the agent's run_command tool.
|
|
7
|
+
*/
|
|
8
|
+
export async function executeDefense(action, target, sendMessage) {
|
|
9
|
+
const defensePrompts = {
|
|
10
|
+
block_ip: `Block the IP address ${target} using iptables. Run:
|
|
11
|
+
iptables -A INPUT -s ${target} -j DROP
|
|
12
|
+
Then verify with: iptables -L -n | grep ${target}`,
|
|
13
|
+
kill_process: `Kill the suspicious process: ${target}. Run:
|
|
14
|
+
kill -9 ${target}
|
|
15
|
+
Then verify it's gone with: ps aux | grep ${target}`,
|
|
16
|
+
close_port: `Close port ${target} using iptables. Run:
|
|
17
|
+
iptables -A INPUT --dport ${target} -j DROP
|
|
18
|
+
Then verify with: ss -tlnp | grep ${target}`,
|
|
19
|
+
rotate_secret: `Rotate the compromised secret for: ${target}
|
|
20
|
+
Generate a new secure random key and update the relevant config file.`,
|
|
21
|
+
isolate_service: `Isolate the service: ${target}
|
|
22
|
+
Stop the service and block its network access:
|
|
23
|
+
systemctl stop ${target} 2>/dev/null
|
|
24
|
+
iptables -A OUTPUT -m owner --uid-owner $(id -u ${target}) -j DROP 2>/dev/null`,
|
|
25
|
+
deploy_honeypot: `Deploy a honeypot for: ${target}
|
|
26
|
+
Start a fake service that logs all connection attempts.
|
|
27
|
+
Use: ncat -l -k -p ${target} -c 'echo "SSH-2.0-OpenSSH_8.2p1"; cat >> /tmp/honeypot.log' &`,
|
|
28
|
+
};
|
|
29
|
+
const prompt = defensePrompts[action] || `Execute defense action "${action}" against target "${target}".`;
|
|
30
|
+
await sendMessage(prompt);
|
|
31
|
+
return {
|
|
32
|
+
id: randomUUID().slice(0, 8),
|
|
33
|
+
action: action,
|
|
34
|
+
target,
|
|
35
|
+
reason: `Auto-response to detected threat`,
|
|
36
|
+
autoApproved: true,
|
|
37
|
+
reversible: action === 'block_ip' || action === 'close_port',
|
|
38
|
+
timestamp: Date.now(),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Undo a reversible defense action.
|
|
43
|
+
*/
|
|
44
|
+
export async function undoDefense(defense, sendMessage) {
|
|
45
|
+
if (!defense.reversible)
|
|
46
|
+
return false;
|
|
47
|
+
const undoPrompts = {
|
|
48
|
+
block_ip: `Unblock IP address ${defense.target}. Run:
|
|
49
|
+
iptables -D INPUT -s ${defense.target} -j DROP`,
|
|
50
|
+
close_port: `Re-open port ${defense.target}. Run:
|
|
51
|
+
iptables -D INPUT --dport ${defense.target} -j DROP`,
|
|
52
|
+
};
|
|
53
|
+
const prompt = undoPrompts[defense.action];
|
|
54
|
+
if (!prompt)
|
|
55
|
+
return false;
|
|
56
|
+
await sendMessage(prompt);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=responder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responder.js","sourceRoot":"","sources":["../../../../src/cli/agent/monitor/responder.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAKzC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAA8B,EAC9B,MAAc,EACd,WAAmB;IAEnB,MAAM,cAAc,GAA2B;QAC7C,QAAQ,EAAE,wBAAwB,MAAM;uBACrB,MAAM;0CACa,MAAM,EAAE;QAE9C,YAAY,EAAE,gCAAgC,MAAM;UAC9C,MAAM;4CAC4B,MAAM,EAAE;QAEhD,UAAU,EAAE,cAAc,MAAM;4BACR,MAAM;oCACE,MAAM,EAAE;QAExC,aAAa,EAAE,sCAAsC,MAAM;sEACO;QAElE,eAAe,EAAE,wBAAwB,MAAM;;iBAElC,MAAM;kDAC2B,MAAM,uBAAuB;QAE3E,eAAe,EAAE,0BAA0B,MAAM;;qBAEhC,MAAM,gEAAgE;KACxF,CAAC;IAEF,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,2BAA2B,MAAM,qBAAqB,MAAM,IAAI,CAAC;IAE1G,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IAE1B,OAAO;QACL,EAAE,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5B,MAAM,EAAE,MAAuB;QAC/B,MAAM;QACN,MAAM,EAAE,kCAAkC;QAC1C,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,YAAY;QAC5D,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAsB,EACtB,WAAmB;IAEnB,IAAI,CAAC,OAAO,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAEtC,MAAM,WAAW,GAA2B;QAC1C,QAAQ,EAAE,sBAAsB,OAAO,CAAC,MAAM;uBAC3B,OAAO,CAAC,MAAM,UAAU;QAE3C,UAAU,EAAE,gBAAgB,OAAO,CAAC,MAAM;4BAClB,OAAO,CAAC,MAAM,UAAU;KACjD,CAAC;IAEF,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitor System — System scanner that uses the LLM + run_command to read system state.
|
|
3
|
+
*/
|
|
4
|
+
import type { ScanResult, MonitorCallbacks } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Perform a full system scan by sending the scan prompt to the agent.
|
|
7
|
+
* The agent will use run_command tools to gather system information.
|
|
8
|
+
*/
|
|
9
|
+
export declare function scanSystem(callbacks: MonitorCallbacks): Promise<ScanResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Perform a quick check (subset of full scan) for the watch loop.
|
|
12
|
+
*/
|
|
13
|
+
export declare function quickScan(callbacks: MonitorCallbacks): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Perform a medium check (config drift + packages).
|
|
16
|
+
*/
|
|
17
|
+
export declare function mediumScan(callbacks: MonitorCallbacks): Promise<string>;
|
|
18
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../../src/cli/agent/monitor/scanner.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG/D;;;GAGG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBjF;AAmCD;;GAEG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAW5E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAW7E"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { SCAN_SYSTEM_PROMPT } from './prompts.js';
|
|
2
|
+
/**
|
|
3
|
+
* Perform a full system scan by sending the scan prompt to the agent.
|
|
4
|
+
* The agent will use run_command tools to gather system information.
|
|
5
|
+
*/
|
|
6
|
+
export async function scanSystem(callbacks) {
|
|
7
|
+
callbacks.onScanComplete('scan_start');
|
|
8
|
+
const resultText = await callbacks.sendMessage(SCAN_SYSTEM_PROMPT);
|
|
9
|
+
// Parse structured baseline from the LLM response
|
|
10
|
+
const parsed = parseBaselineFromResponse(resultText);
|
|
11
|
+
const result = {
|
|
12
|
+
processes: parsed.processes || '',
|
|
13
|
+
ports: parsed.ports || '',
|
|
14
|
+
sshConfig: parsed.sshConfig || '',
|
|
15
|
+
firewall: parsed.firewall || '',
|
|
16
|
+
crontabs: parsed.crontabs || '',
|
|
17
|
+
packages: parsed.packages || '',
|
|
18
|
+
recentLogins: parsed.recentLogins || '',
|
|
19
|
+
configChanges: parsed.configChanges || '',
|
|
20
|
+
timestamp: Date.now(),
|
|
21
|
+
};
|
|
22
|
+
callbacks.onScanComplete('scan_complete');
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse the BASELINE_START...BASELINE_END block from the LLM response.
|
|
27
|
+
*/
|
|
28
|
+
function parseBaselineFromResponse(text) {
|
|
29
|
+
const result = {};
|
|
30
|
+
// Extract the structured block
|
|
31
|
+
const baselineMatch = text.match(/BASELINE_START\s*([\s\S]*?)\s*BASELINE_END/);
|
|
32
|
+
if (baselineMatch) {
|
|
33
|
+
result.rawBaseline = baselineMatch[1].trim();
|
|
34
|
+
}
|
|
35
|
+
// Also extract raw command outputs for backup
|
|
36
|
+
const sections = [
|
|
37
|
+
{ key: 'processes', pattern: /ps aux[\s\S]*?(?=\n(?:ss |cat |crontab|iptables|last |find )|$)/i },
|
|
38
|
+
{ key: 'ports', pattern: /ss -tlnp[\s\S]*?(?=\n(?:cat |crontab|iptables|last |find )|$)/i },
|
|
39
|
+
{ key: 'sshConfig', pattern: /sshd_config[\s\S]*?(?=\n(?:crontab|iptables|last |find )|$)/i },
|
|
40
|
+
{ key: 'firewall', pattern: /iptables[\s\S]*?(?=\n(?:last |find )|$)/i },
|
|
41
|
+
{ key: 'crontabs', pattern: /crontab[\s\S]*?(?=\n(?:iptables|last |find )|$)/i },
|
|
42
|
+
{ key: 'recentLogins', pattern: /last [\s\S]*?(?=\n(?:find )|$)/i },
|
|
43
|
+
{ key: 'configChanges', pattern: /find \/etc[\s\S]*/i },
|
|
44
|
+
];
|
|
45
|
+
for (const { key, pattern } of sections) {
|
|
46
|
+
const match = text.match(pattern);
|
|
47
|
+
if (match) {
|
|
48
|
+
result[key] = match[0].trim();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Perform a quick check (subset of full scan) for the watch loop.
|
|
55
|
+
*/
|
|
56
|
+
export async function quickScan(callbacks) {
|
|
57
|
+
const quickPrompt = `Quick security check. Run these commands and report any anomalies:
|
|
58
|
+
1. ps aux --sort=-%cpu | head -15
|
|
59
|
+
2. ss -tlnp
|
|
60
|
+
3. last -3 2>/dev/null
|
|
61
|
+
|
|
62
|
+
Compare with what you know from the baseline. Report only NEW or CHANGED items.
|
|
63
|
+
If everything matches baseline: ALL_CLEAR
|
|
64
|
+
If anomaly detected: THREAT: {"severity": "...", "category": "...", "title": "...", "details": "...", "source": "..."}`;
|
|
65
|
+
return callbacks.sendMessage(quickPrompt);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Perform a medium check (config drift + packages).
|
|
69
|
+
*/
|
|
70
|
+
export async function mediumScan(callbacks) {
|
|
71
|
+
const mediumPrompt = `Medium security check. Run these commands:
|
|
72
|
+
1. find /etc -newer /etc/hostname -type f -mmin -5 2>/dev/null | head -20
|
|
73
|
+
2. ps aux --sort=-%cpu | head -20
|
|
74
|
+
3. ss -tlnp
|
|
75
|
+
4. dmesg -T 2>/dev/null | tail -10
|
|
76
|
+
|
|
77
|
+
Look for config changes, new processes, new ports. Report:
|
|
78
|
+
ALL_CLEAR or THREAT: {"severity": "...", "category": "...", "title": "...", "details": "...", "source": "..."}`;
|
|
79
|
+
return callbacks.sendMessage(mediumPrompt);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../../../src/cli/agent/monitor/scanner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,SAA2B;IAC1D,SAAS,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IAEvC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAEnE,kDAAkD;IAClD,MAAM,MAAM,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAC;IAErD,MAAM,MAAM,GAAe;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;QACjC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;QACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;QAC/B,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE;QACvC,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,EAAE;QACzC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;IAEF,SAAS,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,yBAAyB,CAAC,IAAY;IAC7C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,+BAA+B;IAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC/E,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,CAAC;IAED,8CAA8C;IAC9C,MAAM,QAAQ,GAAG;QACf,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,kEAAkE,EAAE;QACjG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,gEAAgE,EAAE;QAC3F,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,8DAA8D,EAAE;QAC7F,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,0CAA0C,EAAE;QACxE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,kDAAkD,EAAE;QAChF,EAAE,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,iCAAiC,EAAE;QACnE,EAAE,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,oBAAoB,EAAE;KACxD,CAAC;IAEF,KAAK,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,QAAQ,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,SAA2B;IACzD,MAAM,WAAW,GAAG;;;;;;;uHAOiG,CAAC;IAEtH,OAAO,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,SAA2B;IAC1D,MAAM,YAAY,GAAG;;;;;;;+GAOwF,CAAC;IAE9G,OAAO,SAAS,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitor System — shared types for the security monitoring agent.
|
|
3
|
+
*/
|
|
4
|
+
export type MonitorMode = 'passive' | 'defensive' | 'active';
|
|
5
|
+
export type ThreatSeverity = 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
6
|
+
export type ThreatCategory = 'bruteforce' | 'portscan' | 'exfiltration' | 'malware' | 'config_change' | 'privilege_escalation' | 'secret_leak' | 'anomaly';
|
|
7
|
+
export type DefenseAction = 'block_ip' | 'kill_process' | 'close_port' | 'rotate_secret' | 'isolate_service' | 'deploy_honeypot';
|
|
8
|
+
export interface ThreatEvent {
|
|
9
|
+
id: string;
|
|
10
|
+
severity: ThreatSeverity;
|
|
11
|
+
category: ThreatCategory;
|
|
12
|
+
title: string;
|
|
13
|
+
details: string;
|
|
14
|
+
source: string;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
relatedEvents: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface DefenseRecord {
|
|
19
|
+
id: string;
|
|
20
|
+
action: DefenseAction;
|
|
21
|
+
target: string;
|
|
22
|
+
reason: string;
|
|
23
|
+
autoApproved: boolean;
|
|
24
|
+
reversible: boolean;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
}
|
|
27
|
+
export interface MonitorBaseline {
|
|
28
|
+
processes: ProcessInfo[];
|
|
29
|
+
ports: PortInfo[];
|
|
30
|
+
configs: ConfigSnapshot[];
|
|
31
|
+
packages: PackageInfo[];
|
|
32
|
+
users: UserInfo[];
|
|
33
|
+
crons: CronEntry[];
|
|
34
|
+
timestamp: number;
|
|
35
|
+
}
|
|
36
|
+
export interface ProcessInfo {
|
|
37
|
+
pid: number;
|
|
38
|
+
user: string;
|
|
39
|
+
command: string;
|
|
40
|
+
cpu: number;
|
|
41
|
+
mem: number;
|
|
42
|
+
}
|
|
43
|
+
export interface PortInfo {
|
|
44
|
+
port: number;
|
|
45
|
+
protocol: 'tcp' | 'udp';
|
|
46
|
+
process: string;
|
|
47
|
+
address: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ConfigSnapshot {
|
|
50
|
+
file: string;
|
|
51
|
+
hash: string;
|
|
52
|
+
lastModified: number;
|
|
53
|
+
}
|
|
54
|
+
export interface PackageInfo {
|
|
55
|
+
name: string;
|
|
56
|
+
version: string;
|
|
57
|
+
vulnerabilities: number;
|
|
58
|
+
}
|
|
59
|
+
export interface UserInfo {
|
|
60
|
+
name: string;
|
|
61
|
+
uid: number;
|
|
62
|
+
shell: string;
|
|
63
|
+
lastLogin: number | null;
|
|
64
|
+
}
|
|
65
|
+
export interface CronEntry {
|
|
66
|
+
user: string;
|
|
67
|
+
schedule: string;
|
|
68
|
+
command: string;
|
|
69
|
+
}
|
|
70
|
+
export interface MonitorState {
|
|
71
|
+
mode: MonitorMode;
|
|
72
|
+
uptime: number;
|
|
73
|
+
threats: ThreatEvent[];
|
|
74
|
+
defenses: DefenseRecord[];
|
|
75
|
+
baseline: MonitorBaseline | null;
|
|
76
|
+
lastScan: number;
|
|
77
|
+
}
|
|
78
|
+
export interface ScanResult {
|
|
79
|
+
processes: string;
|
|
80
|
+
ports: string;
|
|
81
|
+
sshConfig: string;
|
|
82
|
+
firewall: string;
|
|
83
|
+
crontabs: string;
|
|
84
|
+
packages: string;
|
|
85
|
+
recentLogins: string;
|
|
86
|
+
configChanges: string;
|
|
87
|
+
timestamp: number;
|
|
88
|
+
}
|
|
89
|
+
export interface Drift {
|
|
90
|
+
category: 'process' | 'port' | 'config' | 'package' | 'user' | 'cron';
|
|
91
|
+
description: string;
|
|
92
|
+
severity: ThreatSeverity;
|
|
93
|
+
details: string;
|
|
94
|
+
}
|
|
95
|
+
export interface MonitorCallbacks {
|
|
96
|
+
sendMessage: (prompt: string) => Promise<string>;
|
|
97
|
+
isAborted: () => boolean;
|
|
98
|
+
onThreat: (threat: ThreatEvent) => void;
|
|
99
|
+
onDefense: (defense: DefenseRecord) => void;
|
|
100
|
+
onScanComplete: (phase: string) => void;
|
|
101
|
+
onStatusUpdate: (status: MonitorState) => void;
|
|
102
|
+
updateStatus: () => void;
|
|
103
|
+
}
|
|
104
|
+
export interface ApprovalRequest {
|
|
105
|
+
id: string;
|
|
106
|
+
action: DefenseAction;
|
|
107
|
+
target: string;
|
|
108
|
+
reason: string;
|
|
109
|
+
severity: ThreatSeverity;
|
|
110
|
+
timestamp: number;
|
|
111
|
+
expiresAt: number;
|
|
112
|
+
}
|
|
113
|
+
export interface ApprovalResponse {
|
|
114
|
+
requestId: string;
|
|
115
|
+
approved: boolean;
|
|
116
|
+
respondedBy: 'web' | 'cli' | 'auto';
|
|
117
|
+
timestamp: number;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/cli/agent/monitor/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/cli/agent/monitor/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MonitorMode, MonitorBaseline, MonitorState, MonitorCallbacks } from './types.js';
|
|
2
|
+
export declare function getMonitorState(): MonitorState | null;
|
|
3
|
+
export declare function runMonitorLoop(callbacks: MonitorCallbacks, mode: MonitorMode, baseline: MonitorBaseline): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../../../src/cli/agent/monitor/watcher.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,YAAY,EACZ,gBAAgB,EAIjB,MAAM,YAAY,CAAC;AAqBpB,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAErD;AAMD,wBAAsB,cAAc,CAClC,SAAS,EAAE,gBAAgB,EAC3B,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAgGf"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monitor System — Continuous watch loop with adaptive intervals.
|
|
3
|
+
*/
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { watchPrompt, analyzeThreatPrompt } from './prompts.js';
|
|
7
|
+
import { quickScan, mediumScan } from './scanner.js';
|
|
8
|
+
import { pushThreatEvent, pushDefenseEvent, requestApproval } from './alerter.js';
|
|
9
|
+
import { executeDefense } from './responder.js';
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Timing constants
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const QUICK_CHECK_INTERVAL = 60_000; // 60 seconds
|
|
14
|
+
const MEDIUM_CHECK_INTERVAL = 300_000; // 5 minutes
|
|
15
|
+
const FULL_CHECK_INTERVAL = 1_800_000; // 30 minutes
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// State
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
let monitorState = null;
|
|
20
|
+
export function getMonitorState() {
|
|
21
|
+
return monitorState;
|
|
22
|
+
}
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Main watch loop
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
export async function runMonitorLoop(callbacks, mode, baseline) {
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
monitorState = {
|
|
29
|
+
mode,
|
|
30
|
+
uptime: 0,
|
|
31
|
+
threats: [],
|
|
32
|
+
defenses: [],
|
|
33
|
+
baseline,
|
|
34
|
+
lastScan: Date.now(),
|
|
35
|
+
};
|
|
36
|
+
let lastQuickCheck = Date.now();
|
|
37
|
+
let lastMediumCheck = Date.now();
|
|
38
|
+
let lastFullCheck = Date.now();
|
|
39
|
+
const d = chalk.dim;
|
|
40
|
+
const shield = mode === 'active' ? '\u2694\uFE0F' : mode === 'defensive' ? '\u{1F6E1}\uFE0F' : '\u{1F50D}';
|
|
41
|
+
process.stdout.write('\n');
|
|
42
|
+
process.stdout.write(d(` ${shield} Monitor loop started (${mode} mode)\n`));
|
|
43
|
+
process.stdout.write(d(' Watching for security anomalies...\n\n'));
|
|
44
|
+
while (!callbacks.isAborted()) {
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
monitorState.uptime = now - startTime;
|
|
47
|
+
// --- Quick check (every 60s) ---
|
|
48
|
+
if (now - lastQuickCheck >= QUICK_CHECK_INTERVAL) {
|
|
49
|
+
lastQuickCheck = now;
|
|
50
|
+
try {
|
|
51
|
+
const result = await quickScan(callbacks);
|
|
52
|
+
if (callbacks.isAborted())
|
|
53
|
+
break;
|
|
54
|
+
const threats = parseThreats(result);
|
|
55
|
+
for (const threat of threats) {
|
|
56
|
+
await handleThreat(threat, mode, callbacks);
|
|
57
|
+
}
|
|
58
|
+
monitorState.lastScan = Date.now();
|
|
59
|
+
callbacks.onStatusUpdate(monitorState);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
if (callbacks.isAborted())
|
|
63
|
+
break;
|
|
64
|
+
process.stdout.write(d(` \u26A0 Quick check error: ${err}\n`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// --- Medium check (every 5min) ---
|
|
68
|
+
if (now - lastMediumCheck >= MEDIUM_CHECK_INTERVAL) {
|
|
69
|
+
lastMediumCheck = now;
|
|
70
|
+
try {
|
|
71
|
+
const result = await mediumScan(callbacks);
|
|
72
|
+
if (callbacks.isAborted())
|
|
73
|
+
break;
|
|
74
|
+
const threats = parseThreats(result);
|
|
75
|
+
for (const threat of threats) {
|
|
76
|
+
await handleThreat(threat, mode, callbacks);
|
|
77
|
+
}
|
|
78
|
+
monitorState.lastScan = Date.now();
|
|
79
|
+
callbacks.onStatusUpdate(monitorState);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
if (callbacks.isAborted())
|
|
83
|
+
break;
|
|
84
|
+
process.stdout.write(d(` \u26A0 Medium check error: ${err}\n`));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// --- Full check (every 30min) ---
|
|
88
|
+
if (now - lastFullCheck >= FULL_CHECK_INTERVAL) {
|
|
89
|
+
lastFullCheck = now;
|
|
90
|
+
try {
|
|
91
|
+
const fullResult = await callbacks.sendMessage(watchPrompt(baseline, mode));
|
|
92
|
+
if (callbacks.isAborted())
|
|
93
|
+
break;
|
|
94
|
+
const threats = parseThreats(fullResult);
|
|
95
|
+
for (const threat of threats) {
|
|
96
|
+
await handleThreat(threat, mode, callbacks);
|
|
97
|
+
}
|
|
98
|
+
monitorState.lastScan = Date.now();
|
|
99
|
+
callbacks.onStatusUpdate(monitorState);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
if (callbacks.isAborted())
|
|
103
|
+
break;
|
|
104
|
+
process.stdout.write(d(` \u26A0 Full check error: ${err}\n`));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Sleep between checks (5 seconds)
|
|
108
|
+
await sleep(5_000);
|
|
109
|
+
}
|
|
110
|
+
monitorState = null;
|
|
111
|
+
process.stdout.write(d('\n Monitor loop stopped.\n'));
|
|
112
|
+
}
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Threat handling
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
async function handleThreat(threat, mode, callbacks) {
|
|
117
|
+
// Add to state
|
|
118
|
+
if (monitorState) {
|
|
119
|
+
monitorState.threats.push(threat);
|
|
120
|
+
}
|
|
121
|
+
// Notify via all channels
|
|
122
|
+
callbacks.onThreat(threat);
|
|
123
|
+
pushThreatEvent(threat);
|
|
124
|
+
const severityColor = {
|
|
125
|
+
critical: chalk.red.bold,
|
|
126
|
+
high: chalk.red,
|
|
127
|
+
medium: chalk.yellow,
|
|
128
|
+
low: chalk.dim,
|
|
129
|
+
info: chalk.dim,
|
|
130
|
+
}[threat.severity];
|
|
131
|
+
process.stdout.write(`\n ${severityColor(`\u26A0 THREAT [${threat.severity.toUpperCase()}]`)} ${threat.title}\n`);
|
|
132
|
+
process.stdout.write(chalk.dim(` ${threat.details}\n`));
|
|
133
|
+
process.stdout.write(chalk.dim(` Source: ${threat.source}\n\n`));
|
|
134
|
+
// In passive mode, only alert — no response
|
|
135
|
+
if (mode === 'passive')
|
|
136
|
+
return;
|
|
137
|
+
// Analyze threat and decide response
|
|
138
|
+
try {
|
|
139
|
+
const analysisResult = await callbacks.sendMessage(analyzeThreatPrompt(threat, mode));
|
|
140
|
+
const response = parseResponse(analysisResult);
|
|
141
|
+
if (response) {
|
|
142
|
+
if (threat.severity === 'critical') {
|
|
143
|
+
// CRITICAL + defensive/active: auto-execute
|
|
144
|
+
const record = await executeDefense(response.action, response.target, callbacks.sendMessage);
|
|
145
|
+
if (monitorState)
|
|
146
|
+
monitorState.defenses.push(record);
|
|
147
|
+
callbacks.onDefense(record);
|
|
148
|
+
pushDefenseEvent(record);
|
|
149
|
+
process.stdout.write(chalk.blue(` \u{1F6E1}\uFE0F Auto-defense: ${response.action} → ${response.target}\n`));
|
|
150
|
+
}
|
|
151
|
+
else if (threat.severity === 'high') {
|
|
152
|
+
// HIGH + defensive/active: request approval from web
|
|
153
|
+
requestApproval(response.action, response.reason, threat.severity);
|
|
154
|
+
process.stdout.write(chalk.yellow(` \u23F3 Awaiting approval: ${response.action} → ${response.target}\n`));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Analysis failed — continue monitoring
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Parsers
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
function parseThreats(text) {
|
|
166
|
+
const threats = [];
|
|
167
|
+
if (text.includes('ALL_CLEAR'))
|
|
168
|
+
return threats;
|
|
169
|
+
// Find all THREAT: {...} blocks
|
|
170
|
+
const threatRegex = /THREAT:\s*(\{[\s\S]*?\})/g;
|
|
171
|
+
let match;
|
|
172
|
+
while ((match = threatRegex.exec(text)) !== null) {
|
|
173
|
+
try {
|
|
174
|
+
const parsed = JSON.parse(match[1]);
|
|
175
|
+
threats.push({
|
|
176
|
+
id: randomUUID().slice(0, 8),
|
|
177
|
+
severity: (parsed.severity || 'info'),
|
|
178
|
+
category: (parsed.category || 'anomaly'),
|
|
179
|
+
title: parsed.title || 'Unknown threat',
|
|
180
|
+
details: parsed.details || '',
|
|
181
|
+
source: parsed.source || 'unknown',
|
|
182
|
+
timestamp: Date.now(),
|
|
183
|
+
relatedEvents: [],
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// Skip unparseable threat
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return threats;
|
|
191
|
+
}
|
|
192
|
+
function parseResponse(text) {
|
|
193
|
+
const responseMatch = text.match(/RESPONSE:\s*(\{[\s\S]*?\})/);
|
|
194
|
+
if (!responseMatch)
|
|
195
|
+
return null;
|
|
196
|
+
try {
|
|
197
|
+
const parsed = JSON.parse(responseMatch[1]);
|
|
198
|
+
return {
|
|
199
|
+
action: parsed.action || '',
|
|
200
|
+
target: parsed.target || '',
|
|
201
|
+
reason: parsed.reason || '',
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
// Helpers
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
function sleep(ms) {
|
|
212
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../../src/cli/agent/monitor/watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -117,6 +117,23 @@ export interface GetBugsRequest extends WSMessage {
|
|
|
117
117
|
export interface PingRequest extends WSMessage {
|
|
118
118
|
type: 'ping';
|
|
119
119
|
}
|
|
120
|
+
export interface StartMonitorRequest extends WSMessage {
|
|
121
|
+
type: 'start_monitor';
|
|
122
|
+
mode: 'passive' | 'defensive' | 'active';
|
|
123
|
+
}
|
|
124
|
+
export interface StopMonitorRequest extends WSMessage {
|
|
125
|
+
type: 'stop_monitor';
|
|
126
|
+
}
|
|
127
|
+
export interface MonitorCommandRequest extends WSMessage {
|
|
128
|
+
type: 'monitor_command';
|
|
129
|
+
command: 'set_mode' | 'rescan' | 'unblock_ip' | 'stop_monitor';
|
|
130
|
+
params?: Record<string, string>;
|
|
131
|
+
}
|
|
132
|
+
export interface ApprovalResponseRequest extends WSMessage {
|
|
133
|
+
type: 'approval_response';
|
|
134
|
+
requestId: string;
|
|
135
|
+
approved: boolean;
|
|
136
|
+
}
|
|
120
137
|
export interface SessionsListResponse extends WSMessage {
|
|
121
138
|
type: 'sessions_list';
|
|
122
139
|
sessions: SessionInfo[];
|
|
@@ -150,6 +167,11 @@ export interface BugsListResponse extends WSMessage {
|
|
|
150
167
|
export interface PongResponse extends WSMessage {
|
|
151
168
|
type: 'pong';
|
|
152
169
|
}
|
|
170
|
+
export interface MonitorStartedResponse extends WSMessage {
|
|
171
|
+
type: 'monitor_started';
|
|
172
|
+
sessionId: string;
|
|
173
|
+
mode: string;
|
|
174
|
+
}
|
|
153
175
|
export interface SessionUpdatedEvent extends WSMessage {
|
|
154
176
|
type: 'session_updated';
|
|
155
177
|
session: SessionInfo;
|
|
@@ -184,6 +206,26 @@ export interface BrowserScreenshotEvent extends WSMessage {
|
|
|
184
206
|
type: 'browser_screenshot';
|
|
185
207
|
screenshot: BrowserScreenshotInfo;
|
|
186
208
|
}
|
|
209
|
+
export interface ThreatDetectedEvent extends WSMessage {
|
|
210
|
+
type: 'threat_detected';
|
|
211
|
+
threat: Record<string, unknown>;
|
|
212
|
+
}
|
|
213
|
+
export interface DefenseActivatedEvent extends WSMessage {
|
|
214
|
+
type: 'defense_activated';
|
|
215
|
+
defense: Record<string, unknown>;
|
|
216
|
+
}
|
|
217
|
+
export interface ApprovalRequestEvent extends WSMessage {
|
|
218
|
+
type: 'approval_request';
|
|
219
|
+
request: Record<string, unknown>;
|
|
220
|
+
}
|
|
221
|
+
export interface MonitorStatusEvent extends WSMessage {
|
|
222
|
+
type: 'monitor_status';
|
|
223
|
+
mode: string;
|
|
224
|
+
uptime: number;
|
|
225
|
+
threatCount: number;
|
|
226
|
+
defenseCount: number;
|
|
227
|
+
lastScan: number;
|
|
228
|
+
}
|
|
187
229
|
export interface ChatStartedEvent extends WSMessage {
|
|
188
230
|
type: 'chat_started';
|
|
189
231
|
chatId: string;
|
|
@@ -223,11 +265,15 @@ export interface ChatErrorEvent extends WSMessage {
|
|
|
223
265
|
chatId: string;
|
|
224
266
|
error: string;
|
|
225
267
|
}
|
|
226
|
-
export type ControlRequest = ListSessionsRequest | StartAutoRequest | StartSecurityRequest | AbortSessionRequest | SubscribeOutputRequest | UnsubscribeOutputRequest | SendChatRequest | GetFindingsRequest | GetBugsRequest | PingRequest;
|
|
268
|
+
export type ControlRequest = ListSessionsRequest | StartAutoRequest | StartSecurityRequest | StartMonitorRequest | StopMonitorRequest | MonitorCommandRequest | ApprovalResponseRequest | AbortSessionRequest | SubscribeOutputRequest | UnsubscribeOutputRequest | SendChatRequest | GetFindingsRequest | GetBugsRequest | PingRequest;
|
|
227
269
|
export interface ControlHandlers {
|
|
228
270
|
listSessions(): SessionInfo[];
|
|
229
271
|
startAuto(goal?: string): string;
|
|
230
272
|
startSecurity(): string;
|
|
273
|
+
startMonitor(mode: 'passive' | 'defensive' | 'active'): string;
|
|
274
|
+
stopMonitor(): boolean;
|
|
275
|
+
handleMonitorCommand(command: string, params?: Record<string, string>): void;
|
|
276
|
+
handleApprovalResponse(requestId: string, approved: boolean): void;
|
|
231
277
|
abortSession(sessionId: string): boolean;
|
|
232
278
|
sendChat(text: string, chatId?: string, mode?: 'normal' | 'skip-permissions'): void;
|
|
233
279
|
getFindings(): Finding[];
|