hackmyagent 0.17.0 → 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.
Files changed (52) hide show
  1. package/dist/.integrity-manifest.json +1 -1
  2. package/dist/checker/skill-identifier.d.ts.map +1 -1
  3. package/dist/checker/skill-identifier.js +4 -3
  4. package/dist/checker/skill-identifier.js.map +1 -1
  5. package/dist/cli.js +201 -58
  6. package/dist/cli.js.map +1 -1
  7. package/dist/hardening/index.d.ts +1 -1
  8. package/dist/hardening/index.d.ts.map +1 -1
  9. package/dist/hardening/index.js +2 -1
  10. package/dist/hardening/index.js.map +1 -1
  11. package/dist/hardening/scanner.d.ts +16 -0
  12. package/dist/hardening/scanner.d.ts.map +1 -1
  13. package/dist/hardening/scanner.js +28 -28
  14. package/dist/hardening/scanner.js.map +1 -1
  15. package/dist/hardening/taxonomy.d.ts +5 -0
  16. package/dist/hardening/taxonomy.d.ts.map +1 -1
  17. package/dist/hardening/taxonomy.js +66 -0
  18. package/dist/hardening/taxonomy.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +4 -3
  22. package/dist/index.js.map +1 -1
  23. package/dist/nanomind-core/analyzers/credential-analyzer.js +6 -0
  24. package/dist/nanomind-core/analyzers/credential-analyzer.js.map +1 -1
  25. package/dist/nanomind-core/compiler/semantic-compiler.js +7 -2
  26. package/dist/nanomind-core/compiler/semantic-compiler.js.map +1 -1
  27. package/dist/nanomind-core/index.d.ts +2 -0
  28. package/dist/nanomind-core/index.d.ts.map +1 -1
  29. package/dist/nanomind-core/index.js +12 -2
  30. package/dist/nanomind-core/index.js.map +1 -1
  31. package/dist/nanomind-core/inference/analm-infer.py +104 -0
  32. package/dist/nanomind-core/inference/security-analyst.d.ts +95 -0
  33. package/dist/nanomind-core/inference/security-analyst.d.ts.map +1 -0
  34. package/dist/nanomind-core/inference/security-analyst.js +372 -0
  35. package/dist/nanomind-core/inference/security-analyst.js.map +1 -0
  36. package/dist/nanomind-core/orchestrate.d.ts +7 -0
  37. package/dist/nanomind-core/orchestrate.d.ts.map +1 -1
  38. package/dist/nanomind-core/orchestrate.js +68 -2
  39. package/dist/nanomind-core/orchestrate.js.map +1 -1
  40. package/dist/nanomind-core/scanner-bridge.d.ts.map +1 -1
  41. package/dist/nanomind-core/scanner-bridge.js +33 -5
  42. package/dist/nanomind-core/scanner-bridge.js.map +1 -1
  43. package/dist/registry/client.d.ts +5 -0
  44. package/dist/registry/client.d.ts.map +1 -1
  45. package/dist/registry/client.js +10 -1
  46. package/dist/registry/client.js.map +1 -1
  47. package/dist/registry/publish.d.ts.map +1 -1
  48. package/dist/registry/publish.js +3 -4
  49. package/dist/registry/publish.js.map +1 -1
  50. package/dist/scanner/external-scanner.js +2 -2
  51. package/dist/scanner/external-scanner.js.map +1 -1
  52. package/package.json +2 -2
@@ -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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"}
@@ -14,11 +14,14 @@
14
14
  * Defense-in-depth: static findings can NEVER be suppressed, only upgraded.
15
15
  */
16
16
  import type { SecurityFinding } from '../hardening/security-check.js';
17
+ import type { AnalystResponse } from './inference/security-analyst.js';
17
18
  export interface OrchestrationOptions {
18
19
  staticOnly?: boolean;
19
20
  ci?: boolean;
20
21
  deep?: boolean;
21
22
  silent?: boolean;
23
+ /** Run AnaLM generative analysis (--analm flag). */
24
+ analm?: boolean;
22
25
  }
23
26
  export interface OrchestrationResult {
24
27
  mergedFindings: SecurityFinding[];
@@ -26,6 +29,10 @@ export interface OrchestrationResult {
26
29
  compiledArtifacts: number;
27
30
  newSemanticFindings: number;
28
31
  integrityStatus: string;
32
+ /** AnaLM results (present when --analm is used and model is available). */
33
+ analystFindings?: AnalystResponse[];
34
+ /** Hint shown to user when analyst is available but not used. */
35
+ analystHint?: string;
29
36
  }
30
37
  /**
31
38
  * Run NanoMind semantic analysis and merge with existing findings.
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrate.d.ts","sourceRoot":"","sources":["../../src/nanomind-core/orchestrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,eAAe,EAAE,EACnC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAsE9B"}
1
+ {"version":3,"file":"orchestrate.d.ts","sourceRoot":"","sources":["../../src/nanomind-core/orchestrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,eAAe,EAAE,CAAC;IACpC,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,eAAe,EAAE,EACnC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAuG9B"}
@@ -55,7 +55,7 @@ exports.orchestrateNanoMind = orchestrateNanoMind;
55
55
  * is unavailable (returns original findings unchanged).
56
56
  */
57
57
  async function orchestrateNanoMind(targetDir, existingFindings, options = {}) {
58
- const { staticOnly = false, ci = false, silent = false } = options;
58
+ const { staticOnly = false, ci = false, silent = false, analm = false } = options;
59
59
  // Skip NanoMind only when explicitly opted out
60
60
  // CI mode still runs NanoMind (deterministic, no cost, better results)
61
61
  if (staticOnly) {
@@ -95,13 +95,39 @@ async function orchestrateNanoMind(targetDir, existingFindings, options = {}) {
95
95
  // Flush NanoMind classification telemetry (non-blocking, best-effort)
96
96
  Promise.resolve().then(() => __importStar(require('../telemetry/nanomind-telemetry.js'))).then(m => m.flushNanoMindTelemetry())
97
97
  .catch(() => { });
98
- return {
98
+ const result = {
99
99
  mergedFindings: nmResult.mergedFindings,
100
100
  nanomindUsed: nmResult.nanomindAvailable,
101
101
  compiledArtifacts: nmResult.compiledArtifacts,
102
102
  newSemanticFindings: newFindings,
103
103
  integrityStatus: nmResult.integrityStatus,
104
104
  };
105
+ // --- Security Analyst (generative model, --analyze flag) ---
106
+ const { isAnalystReady, runAnalystInference } = await Promise.resolve().then(() => __importStar(require('./inference/security-analyst.js')));
107
+ if (analm) {
108
+ const ready = await isAnalystReady();
109
+ if (ready) {
110
+ if (!silent)
111
+ process.stderr.write('Running AnaLM analysis...\n');
112
+ result.analystFindings = await runAnalystOnFindings(nmResult.mergedFindings, runAnalystInference);
113
+ if (!silent && result.analystFindings.length > 0) {
114
+ process.stderr.write(`Analyst: ${result.analystFindings.length} finding(s) analyzed\n`);
115
+ }
116
+ }
117
+ else {
118
+ if (!silent) {
119
+ process.stderr.write('AnaLM not set up. Run: hackmyagent analm setup\n');
120
+ }
121
+ }
122
+ }
123
+ else if (!silent && !ci) {
124
+ // Check if analyst is available but not used -- show hint once
125
+ const ready = await isAnalystReady();
126
+ if (ready) {
127
+ result.analystHint = 'Add --analm for AI-powered threat analysis';
128
+ }
129
+ }
130
+ return result;
105
131
  }
106
132
  catch {
107
133
  // NanoMind unavailable -- static results are still valid
@@ -114,4 +140,44 @@ async function orchestrateNanoMind(targetDir, existingFindings, options = {}) {
114
140
  };
115
141
  }
116
142
  }
143
+ /**
144
+ * Run the analyst model on failed findings that warrant deeper analysis.
145
+ * Targets: suspicious/malicious classifications, credential findings,
146
+ * and high/critical severity findings.
147
+ */
148
+ async function runAnalystOnFindings(findings, runInference) {
149
+ const results = [];
150
+ const failed = findings.filter(f => !f.passed && !f.fixed);
151
+ // Limit to top 10 most important findings to keep inference time reasonable
152
+ const prioritized = failed
153
+ .sort((a, b) => {
154
+ const sevRank = { critical: 4, high: 3, medium: 2, low: 1 };
155
+ return (sevRank[b.severity] ?? 0) - (sevRank[a.severity] ?? 0);
156
+ })
157
+ .slice(0, 10);
158
+ for (const finding of prioritized) {
159
+ // Choose task type based on finding category
160
+ const isCredential = finding.checkId?.startsWith('CRED') ||
161
+ finding.attackClass === 'credential_abuse';
162
+ const taskType = isCredential
163
+ ? 'credentialContextClassification'
164
+ : 'threatAnalysis';
165
+ const content = [
166
+ finding.name,
167
+ finding.description,
168
+ finding.message,
169
+ finding.file ? `File: ${finding.file}` : '',
170
+ finding.attackClass ? `Attack class: ${finding.attackClass}` : '',
171
+ ].filter(Boolean).join('\n');
172
+ const response = await runInference({
173
+ taskType,
174
+ content,
175
+ context: `Check ID: ${finding.checkId}, Severity: ${finding.severity}`,
176
+ });
177
+ if (response) {
178
+ results.push(response);
179
+ }
180
+ }
181
+ return results;
182
+ }
117
183
  //# sourceMappingURL=orchestrate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrate.js","sourceRoot":"","sources":["../../src/nanomind-core/orchestrate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBH,kDA0EC;AA/ED;;;;GAIG;AACI,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,gBAAmC,EACnC,UAAgC,EAAE;IAElC,MAAM,EAAE,UAAU,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEnE,+CAA+C;IAC/C,uEAAuE;IACvE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO;YACL,cAAc,EAAE,CAAC,GAAG,gBAAgB,CAAC;YACrC,YAAY,EAAE,KAAK;YACnB,iBAAiB,EAAE,CAAC;YACpB,mBAAmB,EAAE,CAAC;YACtB,eAAe,EAAE,SAAS;SAC3B,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,0DAA0D;QAC1D,yEAAyE;QACzE,MAAM,EAAE,YAAY,EAAE,GAAG,wDAAa,uBAAuB,GAAC,CAAC;QAC/D,MAAM,eAAe,GAAG,MAAM,YAAY,EAAE,CAAC;QAC7C,IAAI,CAAC,MAAM,IAAI,eAAe,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACvD,CAAC;QAED,sDAAsD;QACtD,gEAAgE;QAChE,iEAAiE;QACjE,mEAAmE;QACnE,mEAAmE;QACnE,MAAM,EAAE,gBAAgB,EAAE,GAAG,wDAAa,+BAA+B,GAAC,CAAC;QAC3E,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;QAC/B,MAAM,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE9B,MAAM,EAAE,eAAe,EAAE,GAAG,wDAAa,qBAAqB,GAAC,CAAC;QAChE,MAAM,QAAQ,GAAuB,MAAM,eAAe,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;QAExF,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;QAEvE,IAAI,CAAC,MAAM,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,aAAa,QAAQ,CAAC,iBAAiB,0BAA0B,WAAW,8BAA8B,CAC3G,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,eAAe,KAAK,OAAO,EAAE,CAAC;YACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,QAAQ,CAAC,eAAe,IAAI,CAAC,CAAC;QACrE,CAAC;QAED,sEAAsE;QACtE,kDAAO,oCAAoC,IACxC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC;aACrC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAEnB,OAAO;YACL,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,YAAY,EAAE,QAAQ,CAAC,iBAAiB;YACxC,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;YAC7C,mBAAmB,EAAE,WAAW;YAChC,eAAe,EAAE,QAAQ,CAAC,eAAe;SAC1C,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;QACzD,OAAO;YACL,cAAc,EAAE,CAAC,GAAG,gBAAgB,CAAC;YACrC,YAAY,EAAE,KAAK;YACnB,iBAAiB,EAAE,CAAC;YACpB,mBAAmB,EAAE,CAAC;YACtB,eAAe,EAAE,aAAa;SAC/B,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"orchestrate.js","sourceRoot":"","sources":["../../src/nanomind-core/orchestrate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scanner-bridge.d.ts","sourceRoot":"","sources":["../../src/nanomind-core/scanner-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAY,MAAM,gCAAgC,CAAC;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AA+CxE,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,eAAe,EAAE,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAmF7B;AA2KD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,eAAe,EAAE,EACjC,WAAW,EAAE,UAAU,EAAE,GACxB,eAAe,EAAE,CAkDnB"}
1
+ {"version":3,"file":"scanner-bridge.d.ts","sourceRoot":"","sources":["../../src/nanomind-core/scanner-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAY,MAAM,gCAAgC,CAAC;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AA+CxE,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,eAAe,EAAE,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAmG7B;AA6LD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,eAAe,EAAE,EACjC,WAAW,EAAE,UAAU,EAAE,GACxB,eAAe,EAAE,CAkDnB"}