hackmyagent 0.17.1 → 0.17.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.
@@ -29,6 +29,8 @@ export { enforceSeverityFloor, validateEnhancement, requireBenignConsensus, reda
29
29
  export { verifyAll, EventChain, generateManifest } from './security/integrity-verifier.js';
30
30
  export { TMEClassifier, getTMEClassifier } from './inference/tme-classifier.js';
31
31
  export type { TMEClassification } from './inference/tme-classifier.js';
32
+ export { getAnalystStatus, isAnalystReady, setupAnalystModel, runAnalystInference, analyzeThreat, assessCredentialContext, assessFalsePositive, generateIntelReport, } from './inference/security-analyst.js';
33
+ export type { AnalystTaskType, AnalystRequest, AnalystResponse, AnalystBackend, AnalystStatus, ThreatAnalysis, CredentialContext, FalsePositiveAssessment, } from './inference/security-analyst.js';
32
34
  export { parseArtifact, classifyArtifactType, computeHash } from './ingestion/artifact-parser.js';
33
35
  export { sanitizeForNanoMind, detectManipulation } from './ingestion/input-sanitizer.js';
34
36
  export type { ParsedArtifact } from './ingestion/artifact-parser.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nanomind-core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGzG,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,aAAa,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC5O,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAG3F,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAChF,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGvE,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClG,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzF,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nanomind-core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGzG,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,aAAa,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC5O,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAG3F,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAChF,YAAY,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGvE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClG,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzF,YAAY,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC"}
@@ -15,7 +15,7 @@
15
15
  * 3. World-class design: compiler architecture, not regex patches
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.detectManipulation = exports.sanitizeForNanoMind = exports.computeHash = exports.classifyArtifactType = exports.parseArtifact = exports.getTMEClassifier = exports.TMEClassifier = exports.generateManifest = exports.EventChain = exports.verifyAll = exports.getAuditEvents = exports.logSecurityEvent = exports.verifyTrainingProvenance = exports.SecurityError = exports.assertASTIntegrity = exports.redactSecretsForNanoMind = exports.requireBenignConsensus = exports.validateEnhancement = exports.enforceSeverityFloor = exports.validateAST = exports.analyzeCode = exports.analyzePrompt = exports.analyzeScope = exports.analyzeGovernance = exports.analyzeCredentials = exports.analyzeCapabilities = exports.SemanticCompiler = exports.DEFAULT_COMPILER_CONFIG = void 0;
18
+ exports.detectManipulation = exports.sanitizeForNanoMind = exports.computeHash = exports.classifyArtifactType = exports.parseArtifact = exports.generateIntelReport = exports.assessFalsePositive = exports.assessCredentialContext = exports.analyzeThreat = exports.runAnalystInference = exports.setupAnalystModel = exports.isAnalystReady = exports.getAnalystStatus = exports.getTMEClassifier = exports.TMEClassifier = exports.generateManifest = exports.EventChain = exports.verifyAll = exports.getAuditEvents = exports.logSecurityEvent = exports.verifyTrainingProvenance = exports.SecurityError = exports.assertASTIntegrity = exports.redactSecretsForNanoMind = exports.requireBenignConsensus = exports.validateEnhancement = exports.enforceSeverityFloor = exports.validateAST = exports.analyzeCode = exports.analyzePrompt = exports.analyzeScope = exports.analyzeGovernance = exports.analyzeCredentials = exports.analyzeCapabilities = exports.SemanticCompiler = exports.DEFAULT_COMPILER_CONFIG = void 0;
19
19
  var types_js_1 = require("./types.js");
20
20
  Object.defineProperty(exports, "DEFAULT_COMPILER_CONFIG", { enumerable: true, get: function () { return types_js_1.DEFAULT_COMPILER_CONFIG; } });
21
21
  // Compiler
@@ -52,10 +52,20 @@ var integrity_verifier_js_1 = require("./security/integrity-verifier.js");
52
52
  Object.defineProperty(exports, "verifyAll", { enumerable: true, get: function () { return integrity_verifier_js_1.verifyAll; } });
53
53
  Object.defineProperty(exports, "EventChain", { enumerable: true, get: function () { return integrity_verifier_js_1.EventChain; } });
54
54
  Object.defineProperty(exports, "generateManifest", { enumerable: true, get: function () { return integrity_verifier_js_1.generateManifest; } });
55
- // Inference
55
+ // Inference -- TME Classifier (ONNX, 10-class labels)
56
56
  var tme_classifier_js_1 = require("./inference/tme-classifier.js");
57
57
  Object.defineProperty(exports, "TMEClassifier", { enumerable: true, get: function () { return tme_classifier_js_1.TMEClassifier; } });
58
58
  Object.defineProperty(exports, "getTMEClassifier", { enumerable: true, get: function () { return tme_classifier_js_1.getTMEClassifier; } });
59
+ // Inference -- Security Analyst (generative, structured JSON)
60
+ var security_analyst_js_1 = require("./inference/security-analyst.js");
61
+ Object.defineProperty(exports, "getAnalystStatus", { enumerable: true, get: function () { return security_analyst_js_1.getAnalystStatus; } });
62
+ Object.defineProperty(exports, "isAnalystReady", { enumerable: true, get: function () { return security_analyst_js_1.isAnalystReady; } });
63
+ Object.defineProperty(exports, "setupAnalystModel", { enumerable: true, get: function () { return security_analyst_js_1.setupAnalystModel; } });
64
+ Object.defineProperty(exports, "runAnalystInference", { enumerable: true, get: function () { return security_analyst_js_1.runAnalystInference; } });
65
+ Object.defineProperty(exports, "analyzeThreat", { enumerable: true, get: function () { return security_analyst_js_1.analyzeThreat; } });
66
+ Object.defineProperty(exports, "assessCredentialContext", { enumerable: true, get: function () { return security_analyst_js_1.assessCredentialContext; } });
67
+ Object.defineProperty(exports, "assessFalsePositive", { enumerable: true, get: function () { return security_analyst_js_1.assessFalsePositive; } });
68
+ Object.defineProperty(exports, "generateIntelReport", { enumerable: true, get: function () { return security_analyst_js_1.generateIntelReport; } });
59
69
  // Ingestion
60
70
  var artifact_parser_js_1 = require("./ingestion/artifact-parser.js");
61
71
  Object.defineProperty(exports, "parseArtifact", { enumerable: true, get: function () { return artifact_parser_js_1.parseArtifact; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nanomind-core/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAgBH,uCAAqD;AAA5C,mHAAA,uBAAuB,OAAA;AAEhC,WAAW;AACX,wEAAmE;AAA1D,wHAAA,gBAAgB,OAAA;AAEzB,YAAY;AACZ,6EAAyE;AAAhE,6HAAA,mBAAmB,OAAA;AAE5B,6EAAwE;AAA/D,4HAAA,kBAAkB,OAAA;AAC3B,6EAAuE;AAA9D,2HAAA,iBAAiB,OAAA;AAC1B,mEAA6D;AAApD,iHAAA,YAAY,OAAA;AACrB,qEAA+D;AAAtD,mHAAA,aAAa,OAAA;AACtB,iEAA2D;AAAlD,+GAAA,WAAW,OAAA;AAEpB,eAAe;AACf,oEAA8D;AAArD,+GAAA,WAAW,OAAA;AAGpB,WAAW;AACX,sEAA4O;AAAnO,2HAAA,oBAAoB,OAAA;AAAE,0HAAA,mBAAmB,OAAA;AAAE,6HAAA,sBAAsB,OAAA;AAAE,+HAAA,wBAAwB,OAAA;AAAE,yHAAA,kBAAkB,OAAA;AAAE,oHAAA,aAAa,OAAA;AAAE,+HAAA,wBAAwB,OAAA;AAAE,uHAAA,gBAAgB,OAAA;AAAE,qHAAA,cAAc,OAAA;AACnM,0EAA2F;AAAlF,kHAAA,SAAS,OAAA;AAAE,mHAAA,UAAU,OAAA;AAAE,yHAAA,gBAAgB,OAAA;AAEhD,YAAY;AACZ,mEAAgF;AAAvE,kHAAA,aAAa,OAAA;AAAE,qHAAA,gBAAgB,OAAA;AAGxC,YAAY;AACZ,qEAAkG;AAAzF,mHAAA,aAAa,OAAA;AAAE,0HAAA,oBAAoB,OAAA;AAAE,iHAAA,WAAW,OAAA;AACzD,qEAAyF;AAAhF,yHAAA,mBAAmB,OAAA;AAAE,wHAAA,kBAAkB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nanomind-core/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAgBH,uCAAqD;AAA5C,mHAAA,uBAAuB,OAAA;AAEhC,WAAW;AACX,wEAAmE;AAA1D,wHAAA,gBAAgB,OAAA;AAEzB,YAAY;AACZ,6EAAyE;AAAhE,6HAAA,mBAAmB,OAAA;AAE5B,6EAAwE;AAA/D,4HAAA,kBAAkB,OAAA;AAC3B,6EAAuE;AAA9D,2HAAA,iBAAiB,OAAA;AAC1B,mEAA6D;AAApD,iHAAA,YAAY,OAAA;AACrB,qEAA+D;AAAtD,mHAAA,aAAa,OAAA;AACtB,iEAA2D;AAAlD,+GAAA,WAAW,OAAA;AAEpB,eAAe;AACf,oEAA8D;AAArD,+GAAA,WAAW,OAAA;AAGpB,WAAW;AACX,sEAA4O;AAAnO,2HAAA,oBAAoB,OAAA;AAAE,0HAAA,mBAAmB,OAAA;AAAE,6HAAA,sBAAsB,OAAA;AAAE,+HAAA,wBAAwB,OAAA;AAAE,yHAAA,kBAAkB,OAAA;AAAE,oHAAA,aAAa,OAAA;AAAE,+HAAA,wBAAwB,OAAA;AAAE,uHAAA,gBAAgB,OAAA;AAAE,qHAAA,cAAc,OAAA;AACnM,0EAA2F;AAAlF,kHAAA,SAAS,OAAA;AAAE,mHAAA,UAAU,OAAA;AAAE,yHAAA,gBAAgB,OAAA;AAEhD,sDAAsD;AACtD,mEAAgF;AAAvE,kHAAA,aAAa,OAAA;AAAE,qHAAA,gBAAgB,OAAA;AAGxC,8DAA8D;AAC9D,uEASyC;AARvC,uHAAA,gBAAgB,OAAA;AAChB,qHAAA,cAAc,OAAA;AACd,wHAAA,iBAAiB,OAAA;AACjB,0HAAA,mBAAmB,OAAA;AACnB,oHAAA,aAAa,OAAA;AACb,8HAAA,uBAAuB,OAAA;AACvB,0HAAA,mBAAmB,OAAA;AACnB,0HAAA,mBAAmB,OAAA;AAarB,YAAY;AACZ,qEAAkG;AAAzF,mHAAA,aAAa,OAAA;AAAE,0HAAA,oBAAoB,OAAA;AAAE,iHAAA,WAAW,OAAA;AACzD,qEAAyF;AAAhF,yHAAA,mBAAmB,OAAA;AAAE,wHAAA,kBAAkB,OAAA"}
@@ -0,0 +1,104 @@
1
+ """
2
+ AnaLM inference helper -- invoked as subprocess by security-analyst.ts.
3
+
4
+ Usage: python3 analm-infer.py <hf_repo> <task_type> <system_prompt_json> <user_message_json>
5
+
6
+ Loads the model, runs inference, extracts JSON from the response.
7
+ Falls back to constructing structured data from prose if JSON extraction fails.
8
+ """
9
+ import json
10
+ import sys
11
+ import re
12
+
13
+ def extract_json(text, task):
14
+ """Try multiple strategies to extract JSON from model output."""
15
+ # Strategy 1: direct parse
16
+ try:
17
+ return json.loads(text)
18
+ except Exception:
19
+ pass
20
+
21
+ # Strategy 2: markdown code fence
22
+ fence = re.search(r'```(?:json)?\s*(.+?)```', text, re.DOTALL)
23
+ if fence:
24
+ try:
25
+ return json.loads(fence.group(1).strip())
26
+ except Exception:
27
+ pass
28
+
29
+ # Strategy 3: find JSON object via brace matching
30
+ depth = 0
31
+ start = -1
32
+ for i, c in enumerate(text):
33
+ if c == '{':
34
+ if depth == 0:
35
+ start = i
36
+ depth += 1
37
+ elif c == '}':
38
+ depth -= 1
39
+ if depth == 0 and start >= 0:
40
+ try:
41
+ return json.loads(text[start:i+1])
42
+ except Exception:
43
+ start = -1
44
+
45
+ # Strategy 4: construct structured data from prose
46
+ if task == "threatAnalysis":
47
+ r = {"confidence": 0.6, "description": text[:300].strip(), "mitigations": []}
48
+ low = text.lower()
49
+ for lv in ["critical", "high", "medium", "low", "none"]:
50
+ if lv in low:
51
+ r["threatLevel"] = lv
52
+ break
53
+ for line in text.split("\n"):
54
+ s = line.strip()
55
+ if s.startswith(("-", "*")) and len(s) > 12:
56
+ r["mitigations"].append(re.sub(r'^[-*]\s*', '', s))
57
+ if r.get("threatLevel"):
58
+ return r
59
+
60
+ if task == "credentialContextClassification":
61
+ low = text.lower()
62
+ for cls in ["real", "test", "example", "placeholder"]:
63
+ if cls in low:
64
+ return {"classification": cls, "reasoning": text[:300].strip(), "confidence": 0.6}
65
+
66
+ if task == "falsePositiveDetection":
67
+ low = text.lower()
68
+ is_fp = "false positive" in low or "not a real" in low or "benign" in low
69
+ return {"isFalsePositive": is_fp, "reasoning": text[:300].strip(), "confidence": 0.5}
70
+
71
+ return None
72
+
73
+
74
+ def main():
75
+ if len(sys.argv) != 5:
76
+ print(json.dumps({"ok": False, "error": "usage: analm-infer.py <repo> <task> <system_json> <user_json>"}))
77
+ sys.exit(1)
78
+
79
+ hf_repo = sys.argv[1]
80
+ task_type = sys.argv[2]
81
+ system_prompt = json.loads(sys.argv[3])
82
+ user_message = json.loads(sys.argv[4])
83
+
84
+ from mlx_lm import load, generate
85
+
86
+ model, tokenizer = load(hf_repo)
87
+
88
+ messages = [
89
+ {"role": "system", "content": system_prompt},
90
+ {"role": "user", "content": user_message},
91
+ ]
92
+
93
+ prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
94
+ response = generate(model, tokenizer, prompt=prompt, max_tokens=512, verbose=False)
95
+
96
+ parsed = extract_json(response, task_type)
97
+ if parsed:
98
+ print(json.dumps({"ok": True, "result": parsed}))
99
+ else:
100
+ print(json.dumps({"ok": False, "raw": response[:500]}))
101
+
102
+
103
+ if __name__ == "__main__":
104
+ main()
@@ -0,0 +1,95 @@
1
+ /**
2
+ * NanoMind Security Analyst -- Generative model inference
3
+ *
4
+ * Runs the nanomind-security-analyst model (SmolLM2-1.7B 12L SFT)
5
+ * for structured security analysis. This is a GENERATIVE model that
6
+ * produces JSON output, NOT a replacement for the TME classifier.
7
+ *
8
+ * Two inference backends (auto-detected):
9
+ * 1. MLX (mlx_lm) -- Apple Silicon only, safetensors (1.8GB)
10
+ * 2. llama.cpp -- Cross-platform, GGUF Q4_K_M (~1GB) [planned]
11
+ *
12
+ * Task types:
13
+ * - threatAnalysis, credentialContextClassification, falsePositiveDetection,
14
+ * artifactClassification, checkExplanation, governanceReasoning, intelReport
15
+ *
16
+ * Gated behind --analm flag. Model downloaded on-demand via `analm setup`.
17
+ */
18
+ export type AnalystTaskType = 'threatAnalysis' | 'credentialContextClassification' | 'falsePositiveDetection' | 'artifactClassification' | 'checkExplanation' | 'governanceReasoning' | 'intelReport';
19
+ export interface AnalystRequest {
20
+ taskType: AnalystTaskType;
21
+ content: string;
22
+ context?: string;
23
+ }
24
+ export interface AnalystResponse {
25
+ taskType: AnalystTaskType;
26
+ result: Record<string, unknown>;
27
+ confidence: number;
28
+ modelVersion: string;
29
+ durationMs: number;
30
+ backend: AnalystBackend;
31
+ }
32
+ export interface ThreatAnalysis {
33
+ threatLevel: string;
34
+ attackVector: string;
35
+ description: string;
36
+ mitigations: string[];
37
+ confidence: number;
38
+ }
39
+ export interface CredentialContext {
40
+ classification: 'real' | 'test' | 'example' | 'placeholder' | 'unknown';
41
+ reasoning: string;
42
+ confidence: number;
43
+ }
44
+ export interface FalsePositiveAssessment {
45
+ isFalsePositive: boolean;
46
+ reasoning: string;
47
+ confidence: number;
48
+ }
49
+ export type AnalystBackend = 'mlx' | 'llamacpp' | 'none';
50
+ export interface AnalystStatus {
51
+ available: boolean;
52
+ backend: AnalystBackend;
53
+ modelCached: boolean;
54
+ platform: string;
55
+ setupCommand: string;
56
+ }
57
+ /**
58
+ * Get the full status of the analyst subsystem.
59
+ * Used by `analyst status` and scan hints.
60
+ */
61
+ export declare function getAnalystStatus(): Promise<AnalystStatus>;
62
+ /**
63
+ * Quick check: is the analyst ready to run right now?
64
+ * Does NOT trigger downloads. Used by orchestrator to decide whether
65
+ * to show the "run analyst setup" hint.
66
+ */
67
+ export declare function isAnalystReady(): Promise<boolean>;
68
+ /**
69
+ * Download the AnaLM model. Called by `analm setup` command.
70
+ * Returns true on success.
71
+ */
72
+ export declare function setupAnalystModel(quiet?: boolean): Promise<boolean>;
73
+ /**
74
+ * Run analyst inference on the given request.
75
+ * Returns null if the analyst is unavailable or inference fails.
76
+ * Caller must gate behind --analyze flag.
77
+ */
78
+ export declare function runAnalystInference(request: AnalystRequest): Promise<AnalystResponse | null>;
79
+ /**
80
+ * Run threat analysis on content flagged as suspicious/malicious.
81
+ */
82
+ export declare function analyzeThreat(content: string, attackClass: string): Promise<ThreatAnalysis | null>;
83
+ /**
84
+ * Assess whether a credential finding is a real credential or test/example.
85
+ */
86
+ export declare function assessCredentialContext(content: string): Promise<CredentialContext | null>;
87
+ /**
88
+ * Assess whether a finding is a false positive.
89
+ */
90
+ export declare function assessFalsePositive(content: string, findingDescription: string): Promise<FalsePositiveAssessment | null>;
91
+ /**
92
+ * Generate an intelligence report summarizing scan findings.
93
+ */
94
+ export declare function generateIntelReport(findingsSummary: string): Promise<AnalystResponse | null>;
95
+ //# sourceMappingURL=security-analyst.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-analyst.d.ts","sourceRoot":"","sources":["../../../src/nanomind-core/inference/security-analyst.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,iCAAiC,GACjC,wBAAwB,GACxB,wBAAwB,GACxB,kBAAkB,GAClB,qBAAqB,GACrB,aAAa,CAAC;AAElB,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAmFD;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,CAW/D;AAED;;;;GAIG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAIvD;AAMD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CA0DvE;AAMD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAajC;AAqDD;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAgBhC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkBnC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAczC;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAKjC"}
@@ -0,0 +1,372 @@
1
+ "use strict";
2
+ /**
3
+ * NanoMind Security Analyst -- Generative model inference
4
+ *
5
+ * Runs the nanomind-security-analyst model (SmolLM2-1.7B 12L SFT)
6
+ * for structured security analysis. This is a GENERATIVE model that
7
+ * produces JSON output, NOT a replacement for the TME classifier.
8
+ *
9
+ * Two inference backends (auto-detected):
10
+ * 1. MLX (mlx_lm) -- Apple Silicon only, safetensors (1.8GB)
11
+ * 2. llama.cpp -- Cross-platform, GGUF Q4_K_M (~1GB) [planned]
12
+ *
13
+ * Task types:
14
+ * - threatAnalysis, credentialContextClassification, falsePositiveDetection,
15
+ * artifactClassification, checkExplanation, governanceReasoning, intelReport
16
+ *
17
+ * Gated behind --analm flag. Model downloaded on-demand via `analm setup`.
18
+ */
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.getAnalystStatus = getAnalystStatus;
21
+ exports.isAnalystReady = isAnalystReady;
22
+ exports.setupAnalystModel = setupAnalystModel;
23
+ exports.runAnalystInference = runAnalystInference;
24
+ exports.analyzeThreat = analyzeThreat;
25
+ exports.assessCredentialContext = assessCredentialContext;
26
+ exports.assessFalsePositive = assessFalsePositive;
27
+ exports.generateIntelReport = generateIntelReport;
28
+ const node_path_1 = require("node:path");
29
+ const node_os_1 = require("node:os");
30
+ const node_child_process_1 = require("node:child_process");
31
+ // ============================================================================
32
+ // Constants
33
+ // ============================================================================
34
+ const HF_REPO = 'opena2a/nanomind-security-analyst';
35
+ const MODEL_VERSION = '0.1.0';
36
+ /** Maximum input length sent to the analyst (tokens are ~4 chars avg) */
37
+ const MAX_INPUT_CHARS = 2048;
38
+ /** Inference timeout. The 1.7B model runs ~2-5s per request on M-series. */
39
+ const INFERENCE_TIMEOUT_MS = 30000;
40
+ // ============================================================================
41
+ // Backend Detection
42
+ // ============================================================================
43
+ let _detectedBackend;
44
+ let _modelCached;
45
+ /**
46
+ * Detect the best available inference backend.
47
+ * MLX is preferred (Apple Silicon), llama.cpp is cross-platform fallback.
48
+ */
49
+ async function detectBackend() {
50
+ if (_detectedBackend !== undefined)
51
+ return _detectedBackend;
52
+ // Try MLX (Apple Silicon only)
53
+ if (process.platform === 'darwin') {
54
+ try {
55
+ await execAsync('uv', [
56
+ 'run', '--with', 'mlx-lm', 'python3', '-c',
57
+ 'import mlx_lm; print("ok")',
58
+ ], { timeout: 15000 });
59
+ _detectedBackend = 'mlx';
60
+ return _detectedBackend;
61
+ }
62
+ catch {
63
+ // MLX not available, try llama.cpp
64
+ }
65
+ }
66
+ // Try llama.cpp (cross-platform) -- planned for future release
67
+ // When implemented, check for llama-cpp-python or llamafile binary
68
+ // try {
69
+ // await execAsync('uv', [
70
+ // 'run', '--with', 'llama-cpp-python', 'python3', '-c',
71
+ // 'from llama_cpp import Llama; print("ok")',
72
+ // ], { timeout: 15_000 });
73
+ // _detectedBackend = 'llamacpp';
74
+ // return _detectedBackend;
75
+ // } catch { /* not available */ }
76
+ _detectedBackend = 'none';
77
+ return _detectedBackend;
78
+ }
79
+ /**
80
+ * Check if the model is already cached locally.
81
+ */
82
+ async function isModelCached() {
83
+ if (_modelCached !== undefined)
84
+ return _modelCached;
85
+ try {
86
+ const checkScript = `
87
+ from huggingface_hub import try_to_load_from_cache
88
+ import json
89
+ path = try_to_load_from_cache("${HF_REPO}", "config.json")
90
+ print(json.dumps({"cached": path is not None}))
91
+ `;
92
+ const result = await execAsync('uv', [
93
+ 'run', '--with', 'huggingface-hub', 'python3', '-c', checkScript,
94
+ ], { timeout: 10000 });
95
+ const parsed = JSON.parse(result.stdout.trim());
96
+ _modelCached = Boolean(parsed.cached);
97
+ }
98
+ catch {
99
+ _modelCached = false;
100
+ }
101
+ return _modelCached;
102
+ }
103
+ /**
104
+ * Get the full status of the analyst subsystem.
105
+ * Used by `analyst status` and scan hints.
106
+ */
107
+ async function getAnalystStatus() {
108
+ const backend = await detectBackend();
109
+ const cached = backend !== 'none' ? await isModelCached() : false;
110
+ return {
111
+ available: backend !== 'none' && cached,
112
+ backend,
113
+ modelCached: cached,
114
+ platform: process.platform === 'darwin' ? 'Apple Silicon (MLX)' : process.platform,
115
+ setupCommand: 'hackmyagent analm setup',
116
+ };
117
+ }
118
+ /**
119
+ * Quick check: is the analyst ready to run right now?
120
+ * Does NOT trigger downloads. Used by orchestrator to decide whether
121
+ * to show the "run analyst setup" hint.
122
+ */
123
+ async function isAnalystReady() {
124
+ const backend = await detectBackend();
125
+ if (backend === 'none')
126
+ return false;
127
+ return isModelCached();
128
+ }
129
+ // ============================================================================
130
+ // Model Setup
131
+ // ============================================================================
132
+ /**
133
+ * Download the AnaLM model. Called by `analm setup` command.
134
+ * Returns true on success.
135
+ */
136
+ async function setupAnalystModel(quiet = false) {
137
+ const backend = await detectBackend();
138
+ if (backend === 'none') {
139
+ if (!quiet) {
140
+ process.stderr.write('No supported inference backend found.\n' +
141
+ (process.platform === 'darwin'
142
+ ? 'Install uv (https://docs.astral.sh/uv/) and run again.\n'
143
+ : 'Cross-platform support (llama.cpp) coming soon.\n' +
144
+ 'Currently requires Apple Silicon Mac with MLX.\n'));
145
+ }
146
+ return false;
147
+ }
148
+ if (await isModelCached()) {
149
+ if (!quiet)
150
+ process.stderr.write('AnaLM model already downloaded.\n');
151
+ return true;
152
+ }
153
+ if (!quiet) {
154
+ process.stderr.write(`Downloading AnaLM v${MODEL_VERSION} ` +
155
+ `(${backend === 'mlx' ? '1.8GB safetensors' : '~1GB GGUF'})...\n`);
156
+ }
157
+ try {
158
+ const downloadScript = `
159
+ from huggingface_hub import snapshot_download
160
+ import json
161
+ path = snapshot_download("${HF_REPO}")
162
+ print(json.dumps({"status": "ok", "path": path}))
163
+ `;
164
+ const result = await execAsync('uv', [
165
+ 'run', '--with', 'huggingface-hub', 'python3', '-c', downloadScript,
166
+ ], { timeout: 600000 }); // 10 min for large model
167
+ const parsed = JSON.parse(result.stdout.trim());
168
+ if (parsed.status === 'ok') {
169
+ _modelCached = true;
170
+ if (!quiet) {
171
+ process.stderr.write('AnaLM model ready.\n');
172
+ process.stderr.write('Use --analm with any scan command for AI-powered analysis.\n');
173
+ }
174
+ return true;
175
+ }
176
+ }
177
+ catch (err) {
178
+ if (!quiet) {
179
+ process.stderr.write(`Download failed: ${err?.message ?? 'unknown error'}\n` +
180
+ 'Check your network connection and try again.\n');
181
+ }
182
+ }
183
+ return false;
184
+ }
185
+ // ============================================================================
186
+ // Inference
187
+ // ============================================================================
188
+ /**
189
+ * Run analyst inference on the given request.
190
+ * Returns null if the analyst is unavailable or inference fails.
191
+ * Caller must gate behind --analyze flag.
192
+ */
193
+ async function runAnalystInference(request) {
194
+ const backend = await detectBackend();
195
+ if (backend === 'none')
196
+ return null;
197
+ const cached = await isModelCached();
198
+ if (!cached)
199
+ return null;
200
+ if (backend === 'mlx') {
201
+ return runMlxInference(request);
202
+ }
203
+ // llamacpp backend -- planned
204
+ return null;
205
+ }
206
+ async function runMlxInference(request) {
207
+ const startMs = Date.now();
208
+ const truncatedContent = request.content.slice(0, MAX_INPUT_CHARS);
209
+ const systemPrompt = getSystemPrompt(request.taskType);
210
+ const userMessage = request.context
211
+ ? `Context: ${request.context}\n\nContent:\n${truncatedContent}`
212
+ : truncatedContent;
213
+ // Use external Python script to avoid template literal escaping issues
214
+ const scriptPath = (0, node_path_1.join)(__dirname, 'analm-infer.py');
215
+ try {
216
+ const result = await execAsync('uv', [
217
+ 'run', '--with', 'mlx-lm', 'python3', scriptPath,
218
+ HF_REPO,
219
+ request.taskType,
220
+ JSON.stringify(systemPrompt),
221
+ JSON.stringify(userMessage),
222
+ ], { timeout: INFERENCE_TIMEOUT_MS });
223
+ // stdout may contain HuggingFace progress bars before the JSON line
224
+ const jsonLine = result.stdout.trim().split('\n')
225
+ .reverse()
226
+ .find(line => line.trim().startsWith('{'));
227
+ if (!jsonLine)
228
+ return null;
229
+ const parsed = JSON.parse(jsonLine.trim());
230
+ const durationMs = Date.now() - startMs;
231
+ if (parsed.ok && parsed.result) {
232
+ return {
233
+ taskType: request.taskType,
234
+ result: parsed.result,
235
+ confidence: typeof parsed.result.confidence === 'number' ? parsed.result.confidence : 0.5,
236
+ modelVersion: `nanomind-analyst-v${MODEL_VERSION}`,
237
+ durationMs,
238
+ backend: 'mlx',
239
+ };
240
+ }
241
+ return null;
242
+ }
243
+ catch {
244
+ return null;
245
+ }
246
+ }
247
+ // ============================================================================
248
+ // Task-Specific Runners
249
+ // ============================================================================
250
+ /**
251
+ * Run threat analysis on content flagged as suspicious/malicious.
252
+ */
253
+ async function analyzeThreat(content, attackClass) {
254
+ const response = await runAnalystInference({
255
+ taskType: 'threatAnalysis',
256
+ content,
257
+ context: `Detected attack class: ${attackClass}`,
258
+ });
259
+ if (!response)
260
+ return null;
261
+ const r = response.result;
262
+ return {
263
+ threatLevel: String(r.threatLevel ?? 'unknown'),
264
+ attackVector: String(r.attackVector ?? attackClass),
265
+ description: String(r.description ?? ''),
266
+ mitigations: Array.isArray(r.mitigations) ? r.mitigations.map(String) : [],
267
+ confidence: response.confidence,
268
+ };
269
+ }
270
+ /**
271
+ * Assess whether a credential finding is a real credential or test/example.
272
+ */
273
+ async function assessCredentialContext(content) {
274
+ const response = await runAnalystInference({
275
+ taskType: 'credentialContextClassification',
276
+ content,
277
+ });
278
+ if (!response)
279
+ return null;
280
+ const r = response.result;
281
+ const validClasses = ['real', 'test', 'example', 'placeholder', 'unknown'];
282
+ const classification = validClasses.includes(r.classification)
283
+ ? r.classification
284
+ : 'unknown';
285
+ return {
286
+ classification,
287
+ reasoning: String(r.reasoning ?? ''),
288
+ confidence: response.confidence,
289
+ };
290
+ }
291
+ /**
292
+ * Assess whether a finding is a false positive.
293
+ */
294
+ async function assessFalsePositive(content, findingDescription) {
295
+ const response = await runAnalystInference({
296
+ taskType: 'falsePositiveDetection',
297
+ content,
298
+ context: `Finding: ${findingDescription}`,
299
+ });
300
+ if (!response)
301
+ return null;
302
+ const r = response.result;
303
+ return {
304
+ isFalsePositive: Boolean(r.isFalsePositive),
305
+ reasoning: String(r.reasoning ?? ''),
306
+ confidence: response.confidence,
307
+ };
308
+ }
309
+ /**
310
+ * Generate an intelligence report summarizing scan findings.
311
+ */
312
+ async function generateIntelReport(findingsSummary) {
313
+ return runAnalystInference({
314
+ taskType: 'intelReport',
315
+ content: findingsSummary,
316
+ });
317
+ }
318
+ // ============================================================================
319
+ // System Prompts
320
+ // ============================================================================
321
+ function getSystemPrompt(taskType) {
322
+ const prompts = {
323
+ threatAnalysis: 'You are a security analyst. Analyze the given content for threats. ' +
324
+ 'Respond with JSON: {"threatLevel": "critical|high|medium|low|none", ' +
325
+ '"attackVector": "string", "description": "string", "mitigations": ["string"], ' +
326
+ '"confidence": 0.0-1.0}',
327
+ credentialContextClassification: 'You are a credential context classifier. Determine if the credential in the content ' +
328
+ 'is real, test, example, or placeholder. ' +
329
+ 'Respond with JSON: {"classification": "real|test|example|placeholder|unknown", ' +
330
+ '"reasoning": "string", "confidence": 0.0-1.0}',
331
+ falsePositiveDetection: 'You are a false positive detector for security findings. ' +
332
+ 'Determine if the described finding is a false positive based on the content. ' +
333
+ 'Respond with JSON: {"isFalsePositive": true|false, "reasoning": "string", ' +
334
+ '"confidence": 0.0-1.0}',
335
+ artifactClassification: 'You are a security artifact classifier. Classify the type of the given artifact. ' +
336
+ 'Respond with JSON: {"artifactType": "string", "reasoning": "string", ' +
337
+ '"confidence": 0.0-1.0}',
338
+ checkExplanation: 'You are a security check explainer. Explain what the security check found and why it matters. ' +
339
+ 'Respond with JSON: {"explanation": "string", "impact": "string", ' +
340
+ '"recommendation": "string", "confidence": 0.0-1.0}',
341
+ governanceReasoning: 'You are a governance analyst. Analyze the governance posture of the given artifact. ' +
342
+ 'Respond with JSON: {"gaps": ["string"], "strengths": ["string"], ' +
343
+ '"recommendations": ["string"], "confidence": 0.0-1.0}',
344
+ intelReport: 'You are a security intelligence analyst. Generate an intelligence report for the scan results. ' +
345
+ 'Respond with JSON: {"summary": "string", "keyFindings": ["string"], ' +
346
+ '"riskAssessment": "string", "recommendations": ["string"], "confidence": 0.0-1.0}',
347
+ };
348
+ return prompts[taskType];
349
+ }
350
+ // ============================================================================
351
+ // Subprocess Helper
352
+ // ============================================================================
353
+ function execAsync(cmd, args, options = {}) {
354
+ return new Promise((resolve, reject) => {
355
+ (0, node_child_process_1.execFile)(cmd, args, {
356
+ timeout: options.timeout ?? 30000,
357
+ maxBuffer: 10 * 1024 * 1024, // 10MB
358
+ env: {
359
+ ...process.env,
360
+ HF_HOME: (0, node_path_1.join)((0, node_os_1.homedir)(), '.cache', 'huggingface'),
361
+ },
362
+ }, (error, stdout, stderr) => {
363
+ if (error) {
364
+ reject(error);
365
+ }
366
+ else {
367
+ resolve({ stdout: String(stdout), stderr: String(stderr) });
368
+ }
369
+ });
370
+ });
371
+ }
372
+ //# sourceMappingURL=security-analyst.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-analyst.js","sourceRoot":"","sources":["../../../src/nanomind-core/inference/security-analyst.ts"],"names":[],"mappings":"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"}