scriptguard 1.0.0

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 (50) hide show
  1. package/README.md +430 -0
  2. package/dist/ai/analyzers/false-positive-filter.d.ts +15 -0
  3. package/dist/ai/analyzers/false-positive-filter.d.ts.map +1 -0
  4. package/dist/ai/analyzers/false-positive-filter.js +162 -0
  5. package/dist/ai/analyzers/false-positive-filter.js.map +1 -0
  6. package/dist/ai/analyzers/insight-generator.d.ts +7 -0
  7. package/dist/ai/analyzers/insight-generator.d.ts.map +1 -0
  8. package/dist/ai/analyzers/insight-generator.js +384 -0
  9. package/dist/ai/analyzers/insight-generator.js.map +1 -0
  10. package/dist/ai/analyzers/threat-detector.d.ts +7 -0
  11. package/dist/ai/analyzers/threat-detector.d.ts.map +1 -0
  12. package/dist/ai/analyzers/threat-detector.js +249 -0
  13. package/dist/ai/analyzers/threat-detector.js.map +1 -0
  14. package/dist/ai/gemini-client.d.ts +47 -0
  15. package/dist/ai/gemini-client.d.ts.map +1 -0
  16. package/dist/ai/gemini-client.js +222 -0
  17. package/dist/ai/gemini-client.js.map +1 -0
  18. package/dist/ai/index.d.ts +8 -0
  19. package/dist/ai/index.d.ts.map +1 -0
  20. package/dist/ai/index.js +19 -0
  21. package/dist/ai/index.js.map +1 -0
  22. package/dist/ai/prompts.d.ts +11 -0
  23. package/dist/ai/prompts.d.ts.map +1 -0
  24. package/dist/ai/prompts.js +212 -0
  25. package/dist/ai/prompts.js.map +1 -0
  26. package/dist/cli.d.ts +4 -0
  27. package/dist/cli.d.ts.map +1 -0
  28. package/dist/cli.js +283 -0
  29. package/dist/cli.js.map +1 -0
  30. package/dist/index.d.ts +6 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +16 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/scanners/index.d.ts +10 -0
  35. package/dist/scanners/index.d.ts.map +1 -0
  36. package/dist/scanners/index.js +202 -0
  37. package/dist/scanners/index.js.map +1 -0
  38. package/dist/scanners/lifecycle.d.ts +10 -0
  39. package/dist/scanners/lifecycle.d.ts.map +1 -0
  40. package/dist/scanners/lifecycle.js +202 -0
  41. package/dist/scanners/lifecycle.js.map +1 -0
  42. package/dist/scanners/patterns.d.ts +4 -0
  43. package/dist/scanners/patterns.d.ts.map +1 -0
  44. package/dist/scanners/patterns.js +188 -0
  45. package/dist/scanners/patterns.js.map +1 -0
  46. package/dist/types/index.d.ts +123 -0
  47. package/dist/types/index.d.ts.map +1 -0
  48. package/dist/types/index.js +4 -0
  49. package/dist/types/index.js.map +1 -0
  50. package/package.json +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threat-detector.js","sourceRoot":"","sources":["../../../src/ai/analyzers/threat-detector.ts"],"names":[],"mappings":";AAAA,sDAAsD;;AAOtD,sDAwBC;AA3BD;;GAEG;AACH,SAAgB,qBAAqB,CACnC,QAAyB,EACzB,UAAuB;IAEvB,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,4BAA4B;IAC5B,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;QACjC,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC;IAEpC,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC;IAEpC,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;IAE9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,QAAyB;IAClD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;IAEnC,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,2CAA2C;QAE3C,+CAA+C;QAC/C,MAAM,aAAa,GAAG;YACpB,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;YAClD,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;YAClD,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;YAC1C,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;YAC1C,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;YAClD,CAAC,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;SAClF,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;QAEzC,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,MAAM;gBAChB,WAAW,EAAE,WAAW,UAAU,8BAA8B,aAAa,2GAA2G;gBACxL,eAAe,EAAE,0BAA0B;gBAC3C,WAAW,EAAE,mIAAmI;gBAChJ,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,aAAa,GAAG,GAAG,CAAC;aACtD,CAAC,CAAC;QACL,CAAC;QAED,2CAA2C;QAC3C,MAAM,qBAAqB,GAAG;YAC5B,4EAA4E;YAC5E,4DAA4D;SAC7D,CAAC;QAEF,IAAI,kBAAkB,GAAG,CAAC,CAAC;QAC3B,KAAK,MAAM,OAAO,IAAI,qBAAqB,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,OAAO;gBAAE,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;QACpD,CAAC;QAED,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,QAAQ;gBAClB,WAAW,EAAE,WAAW,UAAU,0CAA0C,kBAAkB,0EAA0E;gBACxK,eAAe,EAAE,qBAAqB;gBACtC,WAAW,EAAE,kIAAkI;gBAC/I,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,kBAAkB,GAAG,IAAI,CAAC;aAC5D,CAAC,CAAC;QACL,CAAC;QAED,6CAA6C;QAC7C,MAAM,oBAAoB,GAAG;YAC3B,yCAAyC,EAAG,qBAAqB;YACjE,sBAAsB;YACtB,0BAA0B,EAAG,sBAAsB;YACnD,yBAAyB,EAAI,qBAAqB;YAClD,0BAA0B,EAAG,kBAAkB;SAChD,CAAC;QAEF,KAAK,MAAM,OAAO,IAAI,oBAAoB,EAAE,CAAC;YAC3C,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,QAAQ;oBACd,QAAQ,EAAE,MAAM;oBAChB,WAAW,EAAE,WAAW,UAAU,+GAA+G;oBACjJ,eAAe,EAAE,wBAAwB;oBACzC,WAAW,EAAE,+HAA+H;oBAC5I,UAAU,EAAE,GAAG;iBAChB,CAAC,CAAC;gBACH,MAAM,CAAC,2BAA2B;YACpC,CAAC;QACH,CAAC;QAED,gEAAgE;QAChE,MAAM,kBAAkB,GAAG;YACzB,mBAAmB,EAAS,yBAAyB;YACrD,iBAAiB,EAAW,0BAA0B;YACtD,iBAAiB,EAAW,WAAW;YACvC,KAAK,EAAwB,WAAW;SACzC,CAAC;QAEF,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE,CAAC;YAC3C,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,QAAQ;oBACd,QAAQ,EAAE,UAAU;oBACpB,WAAW,EAAE,WAAW,UAAU,sHAAsH;oBACxJ,eAAe,EAAE,yBAAyB;oBAC1C,WAAW,EAAE,iGAAiG;oBAC9G,UAAU,EAAE,GAAG;iBAChB,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAAC,QAAyB;IACxD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;IAEnC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,yCAAyC;IAEzC,yDAAyD;IACzD,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,mBAAmB,GAAG,gDAAgD,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACtG,MAAM,mBAAmB,GAAG,0CAA0C,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAEjG,IAAI,mBAAmB,IAAI,mBAAmB,EAAE,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,UAAU;gBACpB,WAAW,EAAE,oIAAoI;gBACjJ,eAAe,EAAE,8BAA8B;gBAC/C,WAAW,EAAE,0HAA0H;gBACvI,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,MAAM,iBAAiB,GAAG;QACxB,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM;KAC7E,CAAC;IAEF,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACxC,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,oBAAoB,EAAE,CAAC;gBACvB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,oBAAoB,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,MAAM;YAChB,WAAW,EAAE,GAAG,oBAAoB,mHAAmH;YACvJ,eAAe,EAAE,uBAAuB;YACxC,WAAW,EAAE,oIAAoI;YACjJ,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IAED,+DAA+D;IAC/D,IAAI,mBAAmB,GAAG,CAAC,CAAC;IAC5B,KAAK,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,MAAM,cAAc,GAAG,8EAA8E,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpH,IAAI,cAAc,EAAE,CAAC;YACnB,mBAAmB,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,IAAI,mBAAmB,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,MAAM;YAChB,WAAW,EAAE,GAAG,mBAAmB,6GAA6G;YAChJ,eAAe,EAAE,+BAA+B;YAChD,WAAW,EAAE,iIAAiI;YAC9I,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,QAAyB;IACpD,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAE7C,6DAA6D;IAC7D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAC7D,OAAO,CAAC,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CACzE,CAAC;QAEF,IAAI,gBAAgB,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,4JAA4J;gBACzK,eAAe,EAAE,wBAAwB;gBACzC,WAAW,EAAE,iIAAiI;gBAC9I,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,MAAM,gBAAgB,GAAG;QACvB,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW;QACrD,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW;KAClD,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,QAAQ;gBAClB,WAAW,EAAE,iBAAiB,IAAI,0HAA0H;gBAC5J,eAAe,EAAE,+BAA+B;gBAChD,WAAW,EAAE,4HAA4H;gBACzI,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;YACH,MAAM;QACR,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,sFAAsF;IACtF,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE,eAAe,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,uIAAuI;YAC9L,eAAe,EAAE,4BAA4B;YAC7C,WAAW,EAAE,qHAAqH;YAClI,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,WAAmB;IAC7C,MAAM,aAAa,GAAG;QACpB,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS;QACtD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ;QAC7C,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;KAC7C,CAAC;IAEF,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,47 @@
1
+ /** ScriptGuard — Gemini AI client wrapper */
2
+ import type { AIBatchRequest, AIBatchResponse } from '../types/index.js';
3
+ export declare class GeminiClient {
4
+ private client;
5
+ private model;
6
+ private totalTokensUsed;
7
+ constructor(apiKey?: string);
8
+ /**
9
+ * Sanitize script content before sending to API
10
+ * Redacts API keys, tokens, and other sensitive data
11
+ */
12
+ private sanitizeScripts;
13
+ /**
14
+ * Generate cache key from request data
15
+ */
16
+ private getCacheKey;
17
+ /**
18
+ * Check cache for existing response
19
+ */
20
+ private getCachedResponse;
21
+ /**
22
+ * Cache a response
23
+ */
24
+ private setCachedResponse;
25
+ /**
26
+ * Get total tokens used across all requests
27
+ */
28
+ getTotalTokensUsed(): number;
29
+ /**
30
+ * Analyze a batch of packages using Gemini AI
31
+ */
32
+ analyzeBatch(request: AIBatchRequest): Promise<AIBatchResponse>;
33
+ /**
34
+ * Clear the response cache
35
+ */
36
+ clearCache(): void;
37
+ /**
38
+ * Get cache statistics
39
+ */
40
+ getCacheStats(): {
41
+ size: number;
42
+ keys: string[];
43
+ };
44
+ }
45
+ export declare function getGeminiClient(apiKey?: string): GeminiClient;
46
+ export declare function resetGeminiClient(): void;
47
+ //# sourceMappingURL=gemini-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-client.d.ts","sourceRoot":"","sources":["../../src/ai/gemini-client.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAG7C,OAAO,KAAK,EAAU,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAqCjF,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,eAAe,CAAK;gBAEhB,MAAM,CAAC,EAAE,MAAM;IAa3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACI,kBAAkB,IAAI,MAAM;IAInC;;OAEG;IACU,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IA8E5E;;OAEG;IACI,UAAU,IAAI,IAAI;IAIzB;;OAEG;IACI,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;CAMzD;AAOD,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAK7D;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ /** ScriptGuard — Gemini AI client wrapper */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.GeminiClient = void 0;
5
+ exports.getGeminiClient = getGeminiClient;
6
+ exports.resetGeminiClient = resetGeminiClient;
7
+ const generative_ai_1 = require("@google/generative-ai");
8
+ // Dynamic import for p-throttle to avoid ESM/CJS issues
9
+ let pThrottle;
10
+ async function getThrottle() {
11
+ if (!pThrottle) {
12
+ const module = await import('p-throttle');
13
+ pThrottle = module.default || module;
14
+ }
15
+ return pThrottle;
16
+ }
17
+ // Rate limiting: 5 requests per second to stay within free tier limits
18
+ let throttle;
19
+ async function getThrottledGenerateContent() {
20
+ if (!throttle) {
21
+ const pThrottleModule = await getThrottle();
22
+ throttle = pThrottleModule({
23
+ limit: 5,
24
+ interval: 1000,
25
+ });
26
+ }
27
+ return throttle(async (model, prompt) => {
28
+ return await model.generateContent(prompt);
29
+ });
30
+ }
31
+ // In-memory cache with 24-hour TTL
32
+ const cache = new Map();
33
+ const CACHE_TTL = 24 * 60 * 60 * 1000; // 24 hours
34
+ class GeminiClient {
35
+ client;
36
+ model;
37
+ totalTokensUsed = 0;
38
+ constructor(apiKey) {
39
+ const key = apiKey || process.env.GOOGLE_AI_API_KEY;
40
+ if (!key) {
41
+ throw new Error('GOOGLE_AI_API_KEY environment variable not set. ' +
42
+ 'Get your key at: https://makersuite.google.com/app/apikey');
43
+ }
44
+ this.client = new generative_ai_1.GoogleGenerativeAI(key);
45
+ this.model = this.client.getGenerativeModel({ model: 'gemini-3-flash-preview' });
46
+ }
47
+ /**
48
+ * Sanitize script content before sending to API
49
+ * Redacts API keys, tokens, and other sensitive data
50
+ */
51
+ sanitizeScripts(scripts) {
52
+ const sanitized = {};
53
+ for (const [name, content] of Object.entries(scripts)) {
54
+ let cleaned = content;
55
+ // Redact common secret patterns
56
+ const secretPatterns = [
57
+ /(?:api[_-]?key|apikey|secret[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{20,}['"]?/gi,
58
+ /bearer\s+[a-zA-Z0-9_\-]{20,}/gi,
59
+ /sk-[a-zA-Z0-9]{48}/g, // OpenAI API keys
60
+ /ghp_[a-zA-Z0-9]{36}/g, // GitHub tokens
61
+ /gho_[a-zA-Z0-9]{36}/g, // GitHub OAuth tokens
62
+ /ghu_[a-zA-Z0-9]{36}/g, // GitHub user tokens
63
+ /ghs_[a-zA-Z0-9]{36}/g, // GitHub server tokens
64
+ /ghr_[a-zA-Z0-9]{36}/g, // GitHub refresh tokens
65
+ /xoxb-[0-9]{13}-[0-9]{13}-[a-zA-Z0-9]{24}/g, // Slack bot tokens
66
+ /xoxp-[0-9]{13}-[0-9]{13}-[0-9]{12}-[a-zA-Z0-9]{24}/g, // Slack user tokens
67
+ /AKIA[0-9A-Z]{16}/g, // AWS access keys
68
+ ];
69
+ for (const pattern of secretPatterns) {
70
+ cleaned = cleaned.replace(pattern, '[REDACTED_SECRET]');
71
+ }
72
+ sanitized[name] = cleaned;
73
+ }
74
+ return sanitized;
75
+ }
76
+ /**
77
+ * Generate cache key from request data
78
+ */
79
+ getCacheKey(request) {
80
+ const packagesHash = request.packages
81
+ .map(p => `${p.name}@${p.version}:${Object.keys(p.scripts).join(',')}`)
82
+ .sort()
83
+ .join('|');
84
+ return `${request.mode}:${packagesHash}`;
85
+ }
86
+ /**
87
+ * Check cache for existing response
88
+ */
89
+ getCachedResponse(cacheKey) {
90
+ const cached = cache.get(cacheKey);
91
+ if (!cached)
92
+ return null;
93
+ const now = Date.now();
94
+ if (now - cached.timestamp > CACHE_TTL) {
95
+ cache.delete(cacheKey);
96
+ return null;
97
+ }
98
+ return cached.response;
99
+ }
100
+ /**
101
+ * Cache a response
102
+ */
103
+ setCachedResponse(cacheKey, response) {
104
+ cache.set(cacheKey, {
105
+ response,
106
+ timestamp: Date.now(),
107
+ });
108
+ }
109
+ /**
110
+ * Get total tokens used across all requests
111
+ */
112
+ getTotalTokensUsed() {
113
+ return this.totalTokensUsed;
114
+ }
115
+ /**
116
+ * Analyze a batch of packages using Gemini AI
117
+ */
118
+ async analyzeBatch(request) {
119
+ // Check cache first
120
+ const cacheKey = this.getCacheKey(request);
121
+ const cached = this.getCachedResponse(cacheKey);
122
+ if (cached) {
123
+ return cached;
124
+ }
125
+ // Import prompts dynamically
126
+ const { buildPrompt } = await import('./prompts.js');
127
+ // Sanitize all scripts before sending to API
128
+ const sanitizedRequest = {
129
+ ...request,
130
+ packages: request.packages.map(pkg => ({
131
+ ...pkg,
132
+ scripts: this.sanitizeScripts(pkg.scripts),
133
+ })),
134
+ };
135
+ // Build prompt based on mode
136
+ const prompt = buildPrompt(sanitizedRequest, request.mode);
137
+ try {
138
+ // Call Gemini API with rate limiting
139
+ const throttledGenerate = await getThrottledGenerateContent();
140
+ const result = await throttledGenerate(this.model, prompt);
141
+ const response = result.response;
142
+ const text = response.text();
143
+ // Track token usage
144
+ const usage = response.usageMetadata;
145
+ if (usage) {
146
+ this.totalTokensUsed += usage.totalTokenCount || 0;
147
+ }
148
+ // Parse JSON response
149
+ let jsonResponse;
150
+ try {
151
+ // Extract JSON from markdown code blocks if present
152
+ const jsonMatch = text.match(/```json\n?([\s\S]*?)\n?```/) || text.match(/\{[\s\S]*\}/);
153
+ const jsonText = jsonMatch ? jsonMatch[1] || jsonMatch[0] : text;
154
+ jsonResponse = JSON.parse(jsonText);
155
+ }
156
+ catch (parseError) {
157
+ // Fallback: return empty analysis if parsing fails
158
+ console.warn('Failed to parse AI response, returning empty analysis');
159
+ jsonResponse = {
160
+ analyses: sanitizedRequest.packages.map(pkg => ({
161
+ package: pkg.name,
162
+ version: pkg.version,
163
+ falsePositivesFiltered: 0,
164
+ newThreatsDetected: 0,
165
+ insights: [],
166
+ confidence: 0,
167
+ tokensUsed: 0,
168
+ })),
169
+ totalTokensUsed: usage?.totalTokenCount || 0,
170
+ };
171
+ }
172
+ // Cache the response
173
+ this.setCachedResponse(cacheKey, jsonResponse);
174
+ return jsonResponse;
175
+ }
176
+ catch (error) {
177
+ // Handle API errors gracefully
178
+ if (error.status === 429) {
179
+ throw new Error('Rate limit exceeded. Please try again later.');
180
+ }
181
+ else if (error.status === 401) {
182
+ throw new Error('Invalid API key. Please check your GOOGLE_AI_API_KEY.');
183
+ }
184
+ else if (error.code === 'ECONNABORTED' || error.message?.includes('timeout')) {
185
+ throw new Error('Request timeout. The AI service took too long to respond.');
186
+ }
187
+ else {
188
+ throw new Error(`AI analysis failed: ${error.message || 'Unknown error'}`);
189
+ }
190
+ }
191
+ }
192
+ /**
193
+ * Clear the response cache
194
+ */
195
+ clearCache() {
196
+ cache.clear();
197
+ }
198
+ /**
199
+ * Get cache statistics
200
+ */
201
+ getCacheStats() {
202
+ return {
203
+ size: cache.size,
204
+ keys: Array.from(cache.keys()),
205
+ };
206
+ }
207
+ }
208
+ exports.GeminiClient = GeminiClient;
209
+ /**
210
+ * Create a singleton Gemini client instance
211
+ */
212
+ let clientInstance = null;
213
+ function getGeminiClient(apiKey) {
214
+ if (!clientInstance) {
215
+ clientInstance = new GeminiClient(apiKey);
216
+ }
217
+ return clientInstance;
218
+ }
219
+ function resetGeminiClient() {
220
+ clientInstance = null;
221
+ }
222
+ //# sourceMappingURL=gemini-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-client.js","sourceRoot":"","sources":["../../src/ai/gemini-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /** ScriptGuard — AI module exports */
2
+ export { GeminiClient, getGeminiClient, resetGeminiClient } from './gemini-client.js';
3
+ export { buildPrompt, sanitizeForPrompt } from './prompts.js';
4
+ export { analyzeFalsePositives, getFalsePositiveConfidence, } from './analyzers/false-positive-filter.js';
5
+ export { detectAdvancedThreats, } from './analyzers/threat-detector.js';
6
+ export { generateInsights, } from './analyzers/insight-generator.js';
7
+ export type { AIOptions, AIMode, AIAnalysis, AIInsight, AIBatchRequest, AIBatchResponse, } from '../types/index.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,qBAAqB,GACtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAG1C,YAAY,EACV,SAAS,EACT,MAAM,EACN,UAAU,EACV,SAAS,EACT,cAAc,EACd,eAAe,GAChB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /** ScriptGuard — AI module exports */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.generateInsights = exports.detectAdvancedThreats = exports.getFalsePositiveConfidence = exports.analyzeFalsePositives = exports.sanitizeForPrompt = exports.buildPrompt = exports.resetGeminiClient = exports.getGeminiClient = exports.GeminiClient = void 0;
5
+ var gemini_client_js_1 = require("./gemini-client.js");
6
+ Object.defineProperty(exports, "GeminiClient", { enumerable: true, get: function () { return gemini_client_js_1.GeminiClient; } });
7
+ Object.defineProperty(exports, "getGeminiClient", { enumerable: true, get: function () { return gemini_client_js_1.getGeminiClient; } });
8
+ Object.defineProperty(exports, "resetGeminiClient", { enumerable: true, get: function () { return gemini_client_js_1.resetGeminiClient; } });
9
+ var prompts_js_1 = require("./prompts.js");
10
+ Object.defineProperty(exports, "buildPrompt", { enumerable: true, get: function () { return prompts_js_1.buildPrompt; } });
11
+ Object.defineProperty(exports, "sanitizeForPrompt", { enumerable: true, get: function () { return prompts_js_1.sanitizeForPrompt; } });
12
+ var false_positive_filter_js_1 = require("./analyzers/false-positive-filter.js");
13
+ Object.defineProperty(exports, "analyzeFalsePositives", { enumerable: true, get: function () { return false_positive_filter_js_1.analyzeFalsePositives; } });
14
+ Object.defineProperty(exports, "getFalsePositiveConfidence", { enumerable: true, get: function () { return false_positive_filter_js_1.getFalsePositiveConfidence; } });
15
+ var threat_detector_js_1 = require("./analyzers/threat-detector.js");
16
+ Object.defineProperty(exports, "detectAdvancedThreats", { enumerable: true, get: function () { return threat_detector_js_1.detectAdvancedThreats; } });
17
+ var insight_generator_js_1 = require("./analyzers/insight-generator.js");
18
+ Object.defineProperty(exports, "generateInsights", { enumerable: true, get: function () { return insight_generator_js_1.generateInsights; } });
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":";AAAA,sCAAsC;;;AAEtC,uDAAsF;AAA7E,gHAAA,YAAY,OAAA;AAAE,mHAAA,eAAe,OAAA;AAAE,qHAAA,iBAAiB,OAAA;AACzD,2CAA8D;AAArD,yGAAA,WAAW,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AACvC,iFAG8C;AAF5C,iIAAA,qBAAqB,OAAA;AACrB,sIAAA,0BAA0B,OAAA;AAE5B,qEAEwC;AADtC,2HAAA,qBAAqB,OAAA;AAEvB,yEAE0C;AADxC,wHAAA,gBAAgB,OAAA"}
@@ -0,0 +1,11 @@
1
+ /** ScriptGuard — AI prompt templates for different analysis modes */
2
+ import type { AIMode, AIBatchRequest } from '../types/index.js';
3
+ /**
4
+ * Build the analysis prompt based on mode
5
+ */
6
+ export declare function buildPrompt(request: AIBatchRequest, mode: AIMode): string;
7
+ /**
8
+ * Sanitize script content to remove obvious secrets before sending to AI
9
+ */
10
+ export declare function sanitizeForPrompt(content: string): string;
11
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/ai/prompts.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMzE;AAsMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQzD"}
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ /** ScriptGuard — AI prompt templates for different analysis modes */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.buildPrompt = buildPrompt;
5
+ exports.sanitizeForPrompt = sanitizeForPrompt;
6
+ /**
7
+ * Build the analysis prompt based on mode
8
+ */
9
+ function buildPrompt(request, mode) {
10
+ const basePrompt = getBasePrompt();
11
+ const modePrompt = getModePrompt(mode);
12
+ const packageData = formatPackageData(request);
13
+ return `${basePrompt}\n\n${modePrompt}\n\n${packageData}\n\n${getOutputInstructions(mode)}`;
14
+ }
15
+ /**
16
+ * Base system prompt - context about ScriptGuard and npm security
17
+ */
18
+ function getBasePrompt() {
19
+ return `You are ScriptGuard AI, an expert security analyst specializing in npm package supply chain attacks.
20
+
21
+ Your task is to analyze npm package lifecycle scripts (postinstall, preinstall, prepare, etc.) and provide security insights.
22
+
23
+ ## Context
24
+
25
+ - **Supply chain attacks**: Malicious code often hides in lifecycle scripts that run automatically during \`npm install\`
26
+ - **Common threats**: Remote code execution (curl | bash), credential theft, data exfiltration, obfuscated payloads
27
+ - **False positives**: Many legitimate packages use similar patterns for build tools, platform-specific binaries, or configuration
28
+
29
+ ## Your Role
30
+
31
+ 1. **Distinguish safe from unsafe**: Understand context to identify false positives
32
+ 2. **Detect advanced threats**: Identify obfuscated code, novel attack patterns, multi-stage attacks
33
+ 3. **Provide actionable insights**: Explain threats clearly and suggest remediation steps
34
+
35
+ ## Safety Rules
36
+
37
+ - **DO NOT** execute any code - analyze only
38
+ - **Assume malicious intent** unless there's clear evidence of legitimacy
39
+ - **Flag suspicious patterns** even if they might be legitimate - better safe than sorry
40
+ - **Consider the package context**: Unknown packages with risky scripts = higher suspicion`;
41
+ }
42
+ /**
43
+ * Mode-specific instructions
44
+ */
45
+ function getModePrompt(mode) {
46
+ switch (mode) {
47
+ case 'basic':
48
+ return `## Analysis Mode: Basic
49
+
50
+ Focus on identifying **false positives** from regex pattern matching.
51
+
52
+ For each package with findings:
53
+ 1. Analyze the script content and context
54
+ 2. Determine if the pattern match represents a real threat or a false positive
55
+ 3. Consider: Is this a well-known package? Does the pattern serve a legitimate purpose?
56
+ 4. Provide brief explanation for your decision
57
+
58
+ **Time constraint**: Quick analysis, focus on obvious false positives`;
59
+ case 'standard':
60
+ return `## Analysis Mode: Standard
61
+
62
+ Provide comprehensive security analysis for each package.
63
+
64
+ For each package:
65
+ 1. **False positive analysis**: Determine which regex matches are false positives
66
+ 2. **Threat detection**: Identify advanced threats (obfuscation, novel patterns, multi-stage attacks)
67
+ 3. **Contextual understanding**: What does this script actually do?
68
+ 4. **Risk assessment**: Overall confidence in your analysis
69
+
70
+ **Output**: Balanced depth - detailed analysis without excessive detail`;
71
+ case 'thorough':
72
+ return `## Analysis Mode: Thorough
73
+
74
+ Perform deep security analysis with cross-script correlation.
75
+
76
+ For each package:
77
+ 1. **Comprehensive false positive analysis**: Examine each finding in detail
78
+ 2. **Advanced threat detection**: Identify obfuscation, encoding, polyglot code, novel attack patterns
79
+ 3. **Cross-script correlation**: Analyze relationships between multiple lifecycle scripts
80
+ 4. **Attack chain identification**: Detect multi-stage attacks across scripts
81
+ 5. **Package reputation context**: Consider package name, version patterns, script complexity
82
+ 6. **Detailed explanations**: Step-by-step breakdown of what the code does
83
+
84
+ **Output**: Maximum depth - leave no stone unturned`;
85
+ }
86
+ }
87
+ /**
88
+ * Format package data for the AI
89
+ */
90
+ function formatPackageData(request) {
91
+ const packages = request.packages.map((pkg, idx) => {
92
+ const scriptsList = Object.entries(pkg.scripts)
93
+ .map(([name, content]) => `\`${name}\`: ${content}`)
94
+ .join('\n ');
95
+ const findingsList = pkg.findings.length > 0
96
+ ? pkg.findings.map(f => ` - Pattern: \`${f.pattern}\` (Risk: ${f.riskLevel})\n` +
97
+ ` Match: \`${f.match.substring(0, 100)}${f.match.length > 100 ? '...' : ''}\``).join('\n')
98
+ : ' (No regex findings)';
99
+ return `## Package ${idx + 1}: ${pkg.name}@${pkg.version}
100
+
101
+ **Lifecycle Scripts:**
102
+ ${scriptsList}
103
+
104
+ **Regex Pattern Findings:**
105
+ ${findingsList}`;
106
+ }).join('\n\n');
107
+ return `## Packages to Analyze
108
+
109
+ Total packages: ${request.packages.length}
110
+
111
+ ${packages}`;
112
+ }
113
+ /**
114
+ * Output format instructions for the AI
115
+ */
116
+ function getOutputInstructions(mode) {
117
+ return `## Required Output Format
118
+
119
+ Respond ONLY with valid JSON in this exact structure:
120
+
121
+ \`\`\`json
122
+ {
123
+ "analyses": [
124
+ {
125
+ "package": "package-name",
126
+ "version": "1.0.0",
127
+ "falsePositivesFiltered": 2,
128
+ "newThreatsDetected": 1,
129
+ "insights": [
130
+ {
131
+ "type": "false-positive",
132
+ "severity": "low",
133
+ "description": "Brief explanation of why this is a false positive",
134
+ "confidence": 0.9
135
+ },
136
+ {
137
+ "type": "threat",
138
+ "severity": "high",
139
+ "description": "Detailed explanation of the threat",
140
+ "attackTechnique": "e.g., DNS tunneling, reverse shell, credential theft",
141
+ "remediation": "Specific steps to mitigate",
142
+ "confidence": 0.85
143
+ }
144
+ ],
145
+ "confidence": 0.88,
146
+ "tokensUsed": 150
147
+ }
148
+ ],
149
+ "totalTokensUsed": 150
150
+ }
151
+ \`\`\`
152
+
153
+ ## Field Descriptions
154
+
155
+ - **type**: Either "false-positive", "threat", or "mitigation"
156
+ - **severity**: "low", "medium", "high", or "critical"
157
+ - **description**: Clear, concise explanation
158
+ - **attackTechnique**: (optional) Name of the attack technique (e.g., "reverse shell", "DNS exfiltration")
159
+ - **remediation**: (optional) Specific steps to fix or mitigate the issue
160
+ - **confidence**: Number from 0.0 to 1.0 indicating your certainty
161
+
162
+ ## Insight Type Guidelines
163
+
164
+ **false-positive**: The regex match is actually safe
165
+ - Example: \`process.env.PORT\` is for config, not exfiltration
166
+ - Example: \`child_process\` compiling native modules
167
+ - Required fields: type, severity, description, confidence
168
+
169
+ **threat**: Confirmed security issue (including missed threats)
170
+ - Example: Obfuscated base64 payload
171
+ - Example: Suspicious network request to unknown domain
172
+ - Required fields: type, severity, description, attackTechnique (optional), remediation, confidence
173
+
174
+ **mitigation**: Remediation advice for confirmed threats
175
+ - Example: "Remove this script entirely" or "Replace with auditable alternative"
176
+ - Required fields: type, severity, description, remediation, confidence
177
+
178
+ ## Confidence Scoring
179
+
180
+ - **0.9-1.0**: Very confident - clear evidence
181
+ - **0.7-0.9**: Confident - strong indicators
182
+ - **0.5-0.7**: Moderately confident - some ambiguity
183
+ - **0.3-0.5**: Low confidence - significant uncertainty
184
+ - **0.0-0.3**: Very uncertain - highly speculative
185
+
186
+ ## Additional Guidelines
187
+
188
+ ${mode === 'basic' ? `- Focus on obvious false positives
189
+ - Keep descriptions brief (1-2 sentences)
190
+ - Only report high-confidence findings (>0.7)` : mode === 'standard' ? `- Provide balanced detail
191
+ - Include both obvious and subtle findings
192
+ - Report moderate-confidence findings (>0.5)` : `- Be exhaustive in your analysis
193
+ - Report all findings regardless of confidence
194
+ - Provide detailed explanations and context
195
+ - Correlate findings across multiple scripts
196
+ - Consider package reputation and naming patterns`}
197
+
198
+ **CRITICAL**: Respond with ONLY the JSON. No markdown formatting, no explanations outside the JSON structure.`;
199
+ }
200
+ /**
201
+ * Sanitize script content to remove obvious secrets before sending to AI
202
+ */
203
+ function sanitizeForPrompt(content) {
204
+ // Redact API keys, tokens, secrets
205
+ return content
206
+ .replace(/(?:api[_-]?key|secret|token)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{20,}['"]?/gi, '[REDACTED_SECRET]')
207
+ .replace(/bearer\s+[a-zA-Z0-9_\-]{20,}/gi, 'bearer [REDACTED_TOKEN]')
208
+ .replace(/sk-[a-zA-Z0-9]{48}/g, 'sk-[REDACTED]')
209
+ .replace(/ghp_[a-zA-Z0-9]{36}/g, 'ghp_[REDACTED]')
210
+ .replace(/AKIA[0-9A-Z]{16}/g, 'AKIA[REDACTED]');
211
+ }
212
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/ai/prompts.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ /** ScriptGuard — CLI entry point */
3
+ export {};
4
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,oCAAoC"}