@maverick006/ai-engine 1.0.2 → 1.0.4

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.
@@ -6,6 +6,7 @@ export interface ExplanationOptions {
6
6
  }
7
7
  /**
8
8
  * Generates contextual explanations for deterministic security findings using NVIDIA NIM.
9
+ * Operates as an optional advisory module; returns deterministic scanner guidance if API key is missing.
9
10
  */
10
11
  export declare class ContextualExplainer {
11
12
  private ai;
@@ -15,6 +16,10 @@ export declare class ContextualExplainer {
15
16
  * Generates a contextual explanation and remediation strategy for a given finding.
16
17
  */
17
18
  explainFinding(finding: NormalizedFinding, options?: ExplanationOptions): Promise<AIExplanation>;
19
+ /**
20
+ * Complete pre-AI secret redaction to ensure credentials never leak into prompt context.
21
+ */
22
+ maskSecrets(text: string): string;
18
23
  private buildPrompt;
19
24
  private parseAIResponse;
20
25
  private generateFallbackExplanation;
@@ -1 +1 @@
1
- {"version":3,"file":"explainer.d.ts","sourceRoot":"","sources":["../src/explainer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGtE,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,EAAE,CAAuB;IACjC,OAAO,CAAC,YAAY,CAAwC;gBAEhD,MAAM,CAAC,EAAE,MAAM;IAU3B;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC;IA0B1G,OAAO,CAAC,WAAW;IA+BnB,OAAO,CAAC,eAAe;IA6BvB,OAAO,CAAC,2BAA2B;CAWpC"}
1
+ {"version":3,"file":"explainer.d.ts","sourceRoot":"","sources":["../src/explainer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGtE,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,EAAE,CAAuB;IACjC,OAAO,CAAC,YAAY,CAAwC;gBAEhD,MAAM,CAAC,EAAE,MAAM;IAU3B;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC;IAkC1G;;OAEG;IACI,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAyBxC,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,eAAe;IAqCvB,OAAO,CAAC,2BAA2B;CAgBpC"}
package/dist/explainer.js CHANGED
@@ -7,6 +7,7 @@ exports.ContextualExplainer = void 0;
7
7
  const openai_1 = __importDefault(require("openai"));
8
8
  /**
9
9
  * Generates contextual explanations for deterministic security findings using NVIDIA NIM.
10
+ * Operates as an optional advisory module; returns deterministic scanner guidance if API key is missing.
10
11
  */
11
12
  class ContextualExplainer {
12
13
  ai = null;
@@ -24,94 +25,127 @@ class ContextualExplainer {
24
25
  * Generates a contextual explanation and remediation strategy for a given finding.
25
26
  */
26
27
  async explainFinding(finding, options = {}) {
27
- if (!this.ai) {
28
- // Fallback if no API key is provided
28
+ const client = options.apiKey
29
+ ? new openai_1.default({ apiKey: options.apiKey, baseURL: 'https://integrate.api.nvidia.com/v1' })
30
+ : this.ai;
31
+ if (!client) {
32
+ // Deterministic fallback when no AI API key is configured
29
33
  return this.generateFallbackExplanation(finding);
30
34
  }
31
35
  try {
32
36
  const modelName = options.model || this.defaultModel;
33
- const prompt = this.buildPrompt(finding, options.codeContext);
34
- const completion = await this.ai.chat.completions.create({
37
+ // MASK ALL SECRETS BEFORE SENDING TO MODEL
38
+ const safeContext = this.maskSecrets(options.codeContext || '').slice(0, 2000); // 2000 chars max context
39
+ const safeFinding = { ...finding, codeSnippet: this.maskSecrets(finding.codeSnippet || '') };
40
+ const prompt = this.buildPrompt(safeFinding, safeContext);
41
+ const completion = await client.chat.completions.create({
35
42
  model: modelName,
36
43
  messages: [{ role: "user", content: prompt }],
37
- temperature: 0.2, // Low temp for more deterministic code fixes
44
+ temperature: 0.2,
38
45
  max_tokens: 1024,
39
46
  });
40
47
  const text = completion.choices[0]?.message?.content || "";
41
48
  return this.parseAIResponse(finding.scanId || 'unknown', text);
42
49
  }
43
50
  catch (error) {
44
- console.error('Failed to generate AI explanation:', error);
45
- return this.generateFallbackExplanation(finding);
51
+ console.warn('AI explanation failed, reverting to deterministic guidance:', error.message);
52
+ return this.generateFallbackExplanation(finding, 'FAILED');
46
53
  }
47
54
  }
55
+ /**
56
+ * Complete pre-AI secret redaction to ensure credentials never leak into prompt context.
57
+ */
58
+ maskSecrets(text) {
59
+ if (!text)
60
+ return text;
61
+ let masked = text;
62
+ // Mask Private Keys
63
+ masked = masked.replace(/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g, '[MASKED_PRIVATE_KEY]');
64
+ // Mask AWS Access Keys
65
+ masked = masked.replace(/\b(AKIA|ASIA|AROA)[0-9A-Z]{16}\b/g, '$1[MASKED_AWS_KEY]');
66
+ // Mask Database Connection Strings (Postgres, MySQL, Mongo, Redis)
67
+ masked = masked.replace(/(?:postgres|postgresql|mysql|mongodb|mongodb\+srv|redis):\/\/[^\s"']+/gi, '[MASKED_DATABASE_URL]');
68
+ // Mask Bearer Tokens
69
+ masked = masked.replace(/Bearer\s+[a-zA-Z0-9_\-\.]+/gi, 'Bearer [MASKED_BEARER_TOKEN]');
70
+ // Mask JWTs
71
+ masked = masked.replace(/eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g, '[MASKED_JWT]');
72
+ // Mask Generic Secrets in code (password = "...", secret: '...', token = "...")
73
+ masked = masked.replace(/(password|secret|token|api[_-]?key|client_secret)["'\s:=]+(["'])(?:(?!\2).)+(\2)/gi, '$1="[MASKED_SECRET]"');
74
+ return masked;
75
+ }
48
76
  buildPrompt(finding, codeContext) {
49
- return `
50
- You are VibeGuard, a strict, deterministic DevSecOps assistant.
51
- A deterministic security scanner has found the following vulnerability.
52
- Do not guess if it's a false positive, assume the scanner is correct.
53
- Your job is to explain the vulnerability clearly to a developer and provide a safe remediation snippet.
54
-
55
- SCANNER FINDING:
56
- Title: ${finding.title}
57
- Severity: ${finding.severity}
58
- Scanner: ${finding.scanner}
59
- File: ${finding.file}
60
- Line: ${finding.line}
61
- Rule: ${finding.ruleId}
62
- Description: ${finding.description}
63
- CWE: ${finding.cwe || 'Unknown'}
64
- OWASP: ${finding.owasp || 'Unknown'}
65
-
66
- ${codeContext ? `CODE CONTEXT:\n${codeContext}` : ''}
67
- ${finding.codeSnippet ? `SNIPPET:\n${finding.codeSnippet}` : ''}
68
-
69
- Format your response exactly as the following JSON. Do not include markdown blocks around the JSON, just output raw JSON:
70
- {
71
- "summary": "A 1-2 sentence summary of what the issue is.",
72
- "details": "A detailed explanation of how this vulnerability works and why it's dangerous.",
73
- "remediation": "A step-by-step guide to fixing the issue.",
74
- "codeFix": "The exact code snippet to replace the vulnerable code. (Optional, if applicable)"
75
- }
76
- `;
77
+ return `You are VibeGuard, a strict DevSecOps assistant.
78
+ A deterministic security scanner detected this vulnerability:
79
+ Title: ${finding.title}
80
+ Severity: ${finding.severity}
81
+ Scanner: ${finding.scanner}
82
+ File: ${finding.file || 'N/A'}
83
+ Line: ${finding.line || 'N/A'}
84
+ Rule: ${finding.ruleId || 'N/A'}
85
+ Description: ${finding.description || 'N/A'}
86
+ CWE: ${finding.cwe || 'Unknown'}
87
+ OWASP: ${finding.owasp || 'Unknown'}
88
+
89
+ ${codeContext ? `CODE CONTEXT:\n${codeContext}` : ''}
90
+ ${finding.codeSnippet ? `SNIPPET:\n${finding.codeSnippet}` : ''}
91
+
92
+ Provide an actionable remediation in pure JSON with no markdown wrapping:
93
+ {
94
+ "summary": "1-2 sentence overview of the vulnerability.",
95
+ "details": "Technical explanation of the security risk.",
96
+ "remediation": "Step-by-step guidance to fix the vulnerability.",
97
+ "codeFix": "The patched code snippet to replace the vulnerable lines."
98
+ }`;
77
99
  }
78
100
  parseAIResponse(findingId, text) {
79
101
  try {
80
- // Strip potential markdown code blocks if the AI disobeyed instructions
81
- const cleanText = text.replace(/^```json\s*/, '').replace(/```\s*$/, '').trim();
102
+ let cleanText = text.trim();
103
+ const jsonMatch = cleanText.match(/\{[\s\S]*\}/);
104
+ if (jsonMatch) {
105
+ cleanText = jsonMatch[0];
106
+ }
82
107
  const parsed = JSON.parse(cleanText);
83
108
  return {
84
109
  id: `explain-${Date.now()}`,
85
110
  findingId,
86
- summary: parsed.summary || 'Explanation generation failed.',
111
+ summary: parsed.summary || 'Security advisory generated.',
87
112
  details: parsed.details || '',
88
113
  remediation: parsed.remediation || '',
89
- codeFix: parsed.codeFix,
114
+ codeFix: parsed.codeFix || undefined,
90
115
  modelUsed: this.defaultModel,
91
- createdAt: new Date()
116
+ createdAt: new Date(),
117
+ isAiAssisted: true,
118
+ verificationStatus: 'SUGGESTED'
92
119
  };
93
120
  }
94
- catch (e) {
121
+ catch {
95
122
  return {
96
123
  id: `explain-${Date.now()}`,
97
124
  findingId,
98
- summary: 'Failed to parse AI response.',
99
- details: 'The AI provided an explanation, but it was not in the expected format.',
100
- remediation: text, // dumping raw text into remediation as fallback
125
+ summary: 'Advisory Guidance',
126
+ details: text.slice(0, 500),
127
+ remediation: 'Inspect the flagged file and apply standard security remediations.',
101
128
  modelUsed: this.defaultModel,
102
- createdAt: new Date()
129
+ createdAt: new Date(),
130
+ isAiAssisted: true,
131
+ verificationStatus: 'SUGGESTED'
103
132
  };
104
133
  }
105
134
  }
106
- generateFallbackExplanation(finding) {
135
+ generateFallbackExplanation(finding, state = 'NOT_CONFIGURED') {
136
+ const isFailed = state === 'FAILED';
107
137
  return {
108
138
  id: `fallback-${Date.now()}`,
109
139
  findingId: finding.scanId,
110
- summary: `Automated summary for ${finding.title}`,
111
- details: finding.description,
112
- remediation: 'No NVIDIA_API_KEY detected. To unlock automatic AI code generation and remediation, please set the NVIDIA_API_KEY environment variable!',
113
- modelUsed: 'fallback',
114
- createdAt: new Date()
140
+ summary: finding.title || 'Deterministic Security Guidance',
141
+ details: finding.description || 'Vulnerability detected by deterministic security scanner.',
142
+ remediation: finding.remediation || (isFailed
143
+ ? 'AI service was temporarily unreachable. Refer to rule guidance or vendor advisory to resolve.'
144
+ : 'Configure NVIDIA_API_KEY in environment to enable optional AI remediation assistance.'),
145
+ modelUsed: 'deterministic-rules',
146
+ createdAt: new Date(),
147
+ isAiAssisted: false,
148
+ verificationStatus: 'NOT_APPLIED'
115
149
  };
116
150
  }
117
151
  }
@@ -1 +1 @@
1
- {"version":3,"file":"explainer.js","sourceRoot":"","sources":["../src/explainer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"explainer.js","sourceRoot":"","sources":["../src/explainer.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './explainer';
2
+ export * from './verifier';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./explainer"), exports);
18
+ __exportStar(require("./verifier"), exports);
18
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,6CAA2B"}
@@ -0,0 +1,24 @@
1
+ import { NormalizedFinding, FindingStatus, ScannerResult } from '@maverick006/types';
2
+ import { SecurityScanner } from '@maverick006/security-engine';
3
+ export interface VerificationRequest {
4
+ finding: NormalizedFinding;
5
+ codeFix: string;
6
+ originalFileContent?: string;
7
+ scanner: SecurityScanner;
8
+ filePath: string;
9
+ }
10
+ export interface VerificationResult {
11
+ originalFinding: NormalizedFinding;
12
+ status: FindingStatus.VERIFIED | FindingStatus.FAILED_VERIFICATION | FindingStatus.NOT_VERIFIED;
13
+ message: string;
14
+ reScanResult?: ScannerResult;
15
+ }
16
+ /**
17
+ * Rescan Verification Engine:
18
+ * Validates AI-suggested code fixes by applying them in an isolated workspace
19
+ * and executing the deterministic scanner to verify the vulnerability is actually gone.
20
+ */
21
+ export declare class RescanVerifier {
22
+ verifyPatch(request: VerificationRequest): Promise<VerificationResult>;
23
+ }
24
+ //# sourceMappingURL=verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAK/D,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,iBAAiB,CAAC;IACnC,MAAM,EAAE,aAAa,CAAC,QAAQ,GAAG,aAAa,CAAC,mBAAmB,GAAG,aAAa,CAAC,YAAY,CAAC;IAChG,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACnB,WAAW,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA+D7E"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.RescanVerifier = void 0;
37
+ const types_1 = require("@maverick006/types");
38
+ const fs = __importStar(require("fs/promises"));
39
+ const path = __importStar(require("path"));
40
+ const os = __importStar(require("os"));
41
+ /**
42
+ * Rescan Verification Engine:
43
+ * Validates AI-suggested code fixes by applying them in an isolated workspace
44
+ * and executing the deterministic scanner to verify the vulnerability is actually gone.
45
+ */
46
+ class RescanVerifier {
47
+ async verifyPatch(request) {
48
+ const { finding, codeFix, scanner, filePath } = request;
49
+ if (!codeFix || !codeFix.trim()) {
50
+ return {
51
+ originalFinding: finding,
52
+ status: types_1.FindingStatus.NOT_VERIFIED,
53
+ message: 'No executable code fix provided to verify'
54
+ };
55
+ }
56
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'vibeguard-verify-'));
57
+ try {
58
+ const relativeTarget = path.isAbsolute(filePath)
59
+ ? path.basename(filePath)
60
+ : filePath;
61
+ const isolatedFilePath = path.join(tempDir, relativeTarget);
62
+ await fs.mkdir(path.dirname(isolatedFilePath), { recursive: true });
63
+ // Write the patched file
64
+ await fs.writeFile(isolatedFilePath, codeFix, 'utf8');
65
+ // Re-run scanner against the isolated workspace
66
+ const rescanResult = await scanner.scan({
67
+ scanId: `verify-${Date.now()}`,
68
+ repositoryPath: tempDir
69
+ });
70
+ // Check if the original finding still exists
71
+ const targetRule = (finding.ruleId || finding.title || '').toLowerCase();
72
+ const stillFails = rescanResult.findings.some(f => {
73
+ const rescanRule = (f.ruleId || f.title || '').toLowerCase();
74
+ return rescanRule === targetRule;
75
+ });
76
+ if (!stillFails) {
77
+ return {
78
+ originalFinding: finding,
79
+ status: types_1.FindingStatus.VERIFIED,
80
+ message: `Verification succeeded: ${scanner.name} confirmed the vulnerability is resolved with no new regressions.`,
81
+ reScanResult: rescanResult
82
+ };
83
+ }
84
+ else {
85
+ return {
86
+ originalFinding: finding,
87
+ status: types_1.FindingStatus.FAILED_VERIFICATION,
88
+ message: `Verification failed: ${scanner.name} still flagged the vulnerability after applying the proposed fix.`,
89
+ reScanResult: rescanResult
90
+ };
91
+ }
92
+ }
93
+ catch (err) {
94
+ return {
95
+ originalFinding: finding,
96
+ status: types_1.FindingStatus.NOT_VERIFIED,
97
+ message: `Verification could not be performed: ${err.message}`
98
+ };
99
+ }
100
+ finally {
101
+ try {
102
+ await fs.rm(tempDir, { recursive: true, force: true });
103
+ }
104
+ catch { }
105
+ }
106
+ }
107
+ }
108
+ exports.RescanVerifier = RescanVerifier;
109
+ //# sourceMappingURL=verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.js","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,23 +1,24 @@
1
- {
2
- "name": "@maverick006/ai-engine",
3
- "version": "1.0.2",
4
- "main": "dist/index.js",
5
- "types": "dist/index.d.ts",
6
- "scripts": {
7
- "build": "tsc",
8
- "clean": "rm -rf dist",
9
- "test": "jest",
10
- "typecheck": "tsc --noEmit"
11
- },
12
- "dependencies": {
13
- "@maverick006/types": "*",
14
- "openai": "^7.8.0"
15
- },
16
- "devDependencies": {
17
- "@types/jest": "^29.5.0",
18
- "@types/node": "^20.0.0",
19
- "jest": "^29.5.0",
20
- "ts-jest": "^29.1.0",
21
- "typescript": "^5.0.0"
22
- }
23
- }
1
+ {
2
+ "name": "@maverick006/ai-engine",
3
+ "version": "1.0.4",
4
+ "description": "VibeGuard AI Engine for intelligent remediation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "clean": "rm -rf dist",
10
+ "test": "jest",
11
+ "typecheck": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "@maverick006/types": "*",
15
+ "openai": "^7.8.0",
16
+ "typescript": "^5.0.0",
17
+ "@types/node": "^20.0.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/jest": "^29.5.0",
21
+ "jest": "^29.5.0",
22
+ "ts-jest": "^29.1.0"
23
+ }
24
+ }