@vfarcic/dot-ai 0.104.0 → 0.105.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.
- package/README.md +0 -1
- package/dist/core/ai-provider-factory.d.ts +90 -0
- package/dist/core/ai-provider-factory.d.ts.map +1 -0
- package/dist/core/ai-provider-factory.js +187 -0
- package/dist/core/ai-provider.interface.d.ts +116 -0
- package/dist/core/ai-provider.interface.d.ts.map +1 -0
- package/dist/core/ai-provider.interface.js +14 -0
- package/dist/core/capabilities.d.ts +3 -3
- package/dist/core/capabilities.d.ts.map +1 -1
- package/dist/core/capabilities.js +4 -4
- package/dist/core/capability-scan-workflow.d.ts.map +1 -1
- package/dist/core/capability-scan-workflow.js +29 -14
- package/dist/core/doc-testing-session.d.ts +1 -1
- package/dist/core/doc-testing-session.js +1 -1
- package/dist/core/error-handling.js +2 -2
- package/dist/core/index.d.ts +4 -6
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +11 -22
- package/dist/core/platform-operations.d.ts +3 -3
- package/dist/core/platform-operations.d.ts.map +1 -1
- package/dist/core/platform-operations.js +6 -6
- package/dist/core/providers/anthropic-provider.d.ts +32 -0
- package/dist/core/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/core/providers/anthropic-provider.js +177 -0
- package/dist/core/providers/vercel-provider.d.ts +34 -0
- package/dist/core/providers/vercel-provider.d.ts.map +1 -0
- package/dist/core/providers/vercel-provider.js +202 -0
- package/dist/core/schema.d.ts +4 -7
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +13 -11
- package/dist/core/unified-creation-session.d.ts.map +1 -1
- package/dist/core/unified-creation-session.js +13 -14
- package/dist/interfaces/mcp.d.ts +1 -1
- package/dist/interfaces/mcp.js +1 -1
- package/dist/interfaces/rest-api.js +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +2 -2
- package/dist/tools/answer-question.d.ts.map +1 -1
- package/dist/tools/answer-question.js +8 -10
- package/dist/tools/build-platform.js +3 -3
- package/dist/tools/generate-manifests.d.ts.map +1 -1
- package/dist/tools/generate-manifests.js +7 -8
- package/dist/tools/organizational-data.d.ts.map +1 -1
- package/dist/tools/organizational-data.js +3 -2
- package/dist/tools/recommend.d.ts.map +1 -1
- package/dist/tools/recommend.js +50 -30
- package/dist/tools/remediate.d.ts.map +1 -1
- package/dist/tools/remediate.js +23 -39
- package/dist/tools/version.d.ts +3 -2
- package/dist/tools/version.d.ts.map +1 -1
- package/dist/tools/version.js +35 -23
- package/package.json +5 -2
- package/prompts/question-generation.md +31 -3
- package/dist/core/claude.d.ts +0 -88
- package/dist/core/claude.d.ts.map +0 -1
- package/dist/core/claude.js +0 -414
package/dist/core/claude.js
DELETED
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Claude Integration Module
|
|
4
|
-
*
|
|
5
|
-
* Handles AI communication, YAML generation, and learning integration
|
|
6
|
-
*/
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
-
}) : function(o, v) {
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
-
var ownKeys = function(o) {
|
|
25
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
-
var ar = [];
|
|
27
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
-
return ar;
|
|
29
|
-
};
|
|
30
|
-
return ownKeys(o);
|
|
31
|
-
};
|
|
32
|
-
return function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
-
};
|
|
43
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
-
exports.ClaudeIntegration = void 0;
|
|
45
|
-
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
46
|
-
const fs = __importStar(require("fs"));
|
|
47
|
-
const path = __importStar(require("path"));
|
|
48
|
-
const shared_prompt_loader_1 = require("./shared-prompt-loader");
|
|
49
|
-
const crypto = __importStar(require("crypto"));
|
|
50
|
-
class ClaudeIntegration {
|
|
51
|
-
client = null;
|
|
52
|
-
apiKey;
|
|
53
|
-
conversationHistory = [];
|
|
54
|
-
interactions = [];
|
|
55
|
-
debugMode;
|
|
56
|
-
constructor(apiKey) {
|
|
57
|
-
this.apiKey = apiKey;
|
|
58
|
-
this.debugMode = process.env.DEBUG_DOT_AI === 'true';
|
|
59
|
-
this.validateApiKey();
|
|
60
|
-
if (this.apiKey && this.shouldInitializeClient()) {
|
|
61
|
-
this.client = new sdk_1.default({
|
|
62
|
-
apiKey: this.apiKey,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
validateApiKey() {
|
|
67
|
-
// Allow test-friendly initialization
|
|
68
|
-
if (this.apiKey === 'test-key' || this.apiKey === 'mock-key') {
|
|
69
|
-
return; // Allow test keys
|
|
70
|
-
}
|
|
71
|
-
if (!this.apiKey) {
|
|
72
|
-
throw new Error('API key is required for Claude integration');
|
|
73
|
-
}
|
|
74
|
-
if (this.apiKey.length === 0) {
|
|
75
|
-
throw new Error('Invalid API key: API key cannot be empty');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
shouldInitializeClient() {
|
|
79
|
-
// Don't initialize for test configurations
|
|
80
|
-
const testKeys = ['test-key', 'mock-key', 'invalid-key'];
|
|
81
|
-
return !testKeys.includes(this.apiKey);
|
|
82
|
-
}
|
|
83
|
-
isTestKey() {
|
|
84
|
-
const testKeys = ['test-key', 'mock-key', 'invalid-key'];
|
|
85
|
-
return testKeys.includes(this.apiKey);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Create debug directory if it doesn't exist
|
|
89
|
-
*/
|
|
90
|
-
ensureDebugDirectory() {
|
|
91
|
-
const debugDir = path.join(process.cwd(), 'tmp', 'debug-ai');
|
|
92
|
-
if (!fs.existsSync(debugDir)) {
|
|
93
|
-
fs.mkdirSync(debugDir, { recursive: true });
|
|
94
|
-
}
|
|
95
|
-
return debugDir;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Generate unique identifier for debug files with operation context
|
|
99
|
-
*/
|
|
100
|
-
generateDebugId(operation) {
|
|
101
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '').split('T');
|
|
102
|
-
const dateTime = timestamp[0] + 'T' + timestamp[1].substring(0, 6);
|
|
103
|
-
const randomHex = crypto.randomBytes(4).toString('hex');
|
|
104
|
-
return `${dateTime}_${randomHex}_${operation}`;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Save AI interaction for debugging when DEBUG_DOT_AI=true
|
|
108
|
-
*/
|
|
109
|
-
debugLogInteraction(debugId, prompt, response, operation = 'ai_call') {
|
|
110
|
-
if (!this.debugMode)
|
|
111
|
-
return;
|
|
112
|
-
try {
|
|
113
|
-
const debugDir = this.ensureDebugDirectory();
|
|
114
|
-
// Save prompt with descriptive naming
|
|
115
|
-
const promptFile = path.join(debugDir, `${debugId}_prompt.md`);
|
|
116
|
-
fs.writeFileSync(promptFile, `# AI Prompt - ${operation}\n\nTimestamp: ${new Date().toISOString()}\nOperation: ${operation}\n\n---\n\n${prompt}`);
|
|
117
|
-
// Save response with matching naming
|
|
118
|
-
const responseFile = path.join(debugDir, `${debugId}_response.md`);
|
|
119
|
-
const responseContent = `# AI Response - ${operation}
|
|
120
|
-
|
|
121
|
-
Timestamp: ${new Date().toISOString()}
|
|
122
|
-
Operation: ${operation}
|
|
123
|
-
Input Tokens: ${response.usage.input_tokens}
|
|
124
|
-
Output Tokens: ${response.usage.output_tokens}
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
${response.content}`;
|
|
129
|
-
fs.writeFileSync(responseFile, responseContent);
|
|
130
|
-
console.log(`🐛 DEBUG: AI interaction logged to tmp/debug-ai/${debugId}_*.md`);
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
console.warn('Failed to log AI debug interaction:', error);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
async sendMessage(message, operation = 'generic') {
|
|
137
|
-
// For test keys, skip client initialization check and continue to mock responses
|
|
138
|
-
if (!this.client && !this.isTestKey()) {
|
|
139
|
-
throw new Error('Claude client not initialized due to missing API key');
|
|
140
|
-
}
|
|
141
|
-
if (this.apiKey === 'invalid-key') {
|
|
142
|
-
throw new Error('Authentication failed: Invalid API key');
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
// Add message to conversation history
|
|
146
|
-
this.conversationHistory.push({ role: 'user', content: message });
|
|
147
|
-
// Use real Claude API if we have a real API key, otherwise fall back to mocks
|
|
148
|
-
if (this.apiKey.startsWith('sk-ant-') && this.client) {
|
|
149
|
-
// Make real API call to Claude with streaming
|
|
150
|
-
const stream = await this.client.messages.create({
|
|
151
|
-
model: process.env.MODEL || 'claude-sonnet-4-5-20250929', // Latest Claude Sonnet 4.5
|
|
152
|
-
max_tokens: 64000,
|
|
153
|
-
messages: [{ role: 'user', content: message }],
|
|
154
|
-
stream: true // Enable streaming by default to support long operations (>10 minutes)
|
|
155
|
-
});
|
|
156
|
-
let content = '';
|
|
157
|
-
let input_tokens = 0;
|
|
158
|
-
let output_tokens = 0;
|
|
159
|
-
for await (const chunk of stream) {
|
|
160
|
-
if (chunk.type === 'message_start') {
|
|
161
|
-
input_tokens = chunk.message.usage.input_tokens;
|
|
162
|
-
}
|
|
163
|
-
else if (chunk.type === 'content_block_delta') {
|
|
164
|
-
if (chunk.delta.type === 'text_delta') {
|
|
165
|
-
content += chunk.delta.text;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else if (chunk.type === 'message_delta') {
|
|
169
|
-
output_tokens = chunk.usage.output_tokens;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const response = {
|
|
173
|
-
content,
|
|
174
|
-
usage: {
|
|
175
|
-
input_tokens,
|
|
176
|
-
output_tokens
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
this.conversationHistory.push({ role: 'assistant', content: response.content });
|
|
180
|
-
// Debug log the interaction if enabled
|
|
181
|
-
if (this.debugMode) {
|
|
182
|
-
const debugId = this.generateDebugId(operation);
|
|
183
|
-
this.debugLogInteraction(debugId, message, response, operation);
|
|
184
|
-
}
|
|
185
|
-
return response;
|
|
186
|
-
}
|
|
187
|
-
// For testing purposes, return mock responses
|
|
188
|
-
let response;
|
|
189
|
-
if (message.toLowerCase().includes('deploy a web application')) {
|
|
190
|
-
response = {
|
|
191
|
-
content: 'I can help you deploy a web application to Kubernetes. Let me guide you through the process of creating the necessary YAML manifests for your deployment.',
|
|
192
|
-
usage: { input_tokens: 10, output_tokens: 25 }
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
else if (message.toLowerCase().includes('recommended resources') &&
|
|
196
|
-
this.conversationHistory.some(msg => msg.content.toLowerCase().includes('nginx'))) {
|
|
197
|
-
response = {
|
|
198
|
-
content: 'For nginx deployment, I recommend starting with 2 replicas, 500m CPU and 512Mi memory per pod. You can adjust these based on your traffic patterns.',
|
|
199
|
-
usage: { input_tokens: 8, output_tokens: 30 }
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
// Default mock response
|
|
204
|
-
response = {
|
|
205
|
-
content: 'I understand you want help with Kubernetes deployment. Could you provide more specific details about what you\'d like to deploy?',
|
|
206
|
-
usage: { input_tokens: message.length / 4, output_tokens: 20 }
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
this.conversationHistory.push({ role: 'assistant', content: response.content });
|
|
210
|
-
// Debug log the interaction if enabled (for mocks too)
|
|
211
|
-
if (this.debugMode) {
|
|
212
|
-
const debugId = this.generateDebugId(`mock-${operation}`);
|
|
213
|
-
this.debugLogInteraction(debugId, message, response, `mock-${operation}`);
|
|
214
|
-
}
|
|
215
|
-
return response;
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
throw new Error(`Claude API error: ${error}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
async generateYAML(resourceType, config) {
|
|
222
|
-
if (!this.client && !this.isTestKey()) {
|
|
223
|
-
throw new Error('Claude client not initialized');
|
|
224
|
-
}
|
|
225
|
-
// Mock YAML generation for testing
|
|
226
|
-
if (resourceType === 'deployment' && config.app === 'nginx') {
|
|
227
|
-
return {
|
|
228
|
-
yaml: `apiVersion: apps/v1
|
|
229
|
-
kind: Deployment
|
|
230
|
-
metadata:
|
|
231
|
-
name: ${config.app}
|
|
232
|
-
labels:
|
|
233
|
-
app: ${config.app}
|
|
234
|
-
spec:
|
|
235
|
-
replicas: ${config.replicas || 1}
|
|
236
|
-
selector:
|
|
237
|
-
matchLabels:
|
|
238
|
-
app: ${config.app}
|
|
239
|
-
template:
|
|
240
|
-
metadata:
|
|
241
|
-
labels:
|
|
242
|
-
app: ${config.app}
|
|
243
|
-
spec:
|
|
244
|
-
containers:
|
|
245
|
-
- name: ${config.app}
|
|
246
|
-
image: ${config.image}
|
|
247
|
-
ports:
|
|
248
|
-
- containerPort: 80`,
|
|
249
|
-
explanation: `This deployment creates ${config.replicas || 1} replica(s) of ${config.app} using the ${config.image} image. The container exposes port 80 for web traffic.`
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
// Default YAML response
|
|
253
|
-
return {
|
|
254
|
-
yaml: `apiVersion: apps/v1
|
|
255
|
-
kind: ${resourceType.charAt(0).toUpperCase() + resourceType.slice(1)}
|
|
256
|
-
metadata:
|
|
257
|
-
name: example-${resourceType}
|
|
258
|
-
spec:
|
|
259
|
-
# Generated configuration would go here`,
|
|
260
|
-
explanation: `This is a basic ${resourceType} manifest. You should customize it based on your specific requirements.`
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
async recordInteraction(interaction) {
|
|
264
|
-
const recordedInteraction = {
|
|
265
|
-
...interaction,
|
|
266
|
-
timestamp: new Date()
|
|
267
|
-
};
|
|
268
|
-
this.interactions.push(recordedInteraction);
|
|
269
|
-
}
|
|
270
|
-
async getSuccessfulPatterns() {
|
|
271
|
-
return this.interactions.filter(interaction => interaction.success);
|
|
272
|
-
}
|
|
273
|
-
getConversationHistory() {
|
|
274
|
-
return [...this.conversationHistory];
|
|
275
|
-
}
|
|
276
|
-
clearConversationHistory() {
|
|
277
|
-
this.conversationHistory = [];
|
|
278
|
-
}
|
|
279
|
-
async generateManifest(spec) {
|
|
280
|
-
if (!this.client && !this.isTestKey()) {
|
|
281
|
-
throw new Error('Claude client not initialized');
|
|
282
|
-
}
|
|
283
|
-
// Simulate manifest generation
|
|
284
|
-
const yamlContent = `
|
|
285
|
-
apiVersion: apps/v1
|
|
286
|
-
kind: Deployment
|
|
287
|
-
metadata:
|
|
288
|
-
name: ${spec.name || 'app'}
|
|
289
|
-
spec:
|
|
290
|
-
replicas: ${spec.replicas || 1}
|
|
291
|
-
selector:
|
|
292
|
-
matchLabels:
|
|
293
|
-
app: ${spec.name || 'app'}
|
|
294
|
-
template:
|
|
295
|
-
metadata:
|
|
296
|
-
labels:
|
|
297
|
-
app: ${spec.name || 'app'}
|
|
298
|
-
spec:
|
|
299
|
-
containers:
|
|
300
|
-
- name: app
|
|
301
|
-
image: ${spec.image || 'nginx:latest'}
|
|
302
|
-
ports:
|
|
303
|
-
- containerPort: 80
|
|
304
|
-
`;
|
|
305
|
-
return yamlContent.trim();
|
|
306
|
-
}
|
|
307
|
-
async analyzeError(error, _context) {
|
|
308
|
-
if (!this.client && !this.isTestKey()) {
|
|
309
|
-
throw new Error('Claude client not initialized');
|
|
310
|
-
}
|
|
311
|
-
// Simulate error analysis
|
|
312
|
-
return `Error analysis: ${error}. Suggested fix: Check the configuration and try again.`;
|
|
313
|
-
}
|
|
314
|
-
async suggestImprovements(_manifest) {
|
|
315
|
-
if (!this.client && !this.isTestKey()) {
|
|
316
|
-
throw new Error('Claude client not initialized');
|
|
317
|
-
}
|
|
318
|
-
// Simulate improvement suggestions
|
|
319
|
-
return [
|
|
320
|
-
'Add resource limits and requests',
|
|
321
|
-
'Consider adding health checks',
|
|
322
|
-
'Add labels for better organization'
|
|
323
|
-
];
|
|
324
|
-
}
|
|
325
|
-
async processUserInput(input, context) {
|
|
326
|
-
if (!this.client && !this.isTestKey()) {
|
|
327
|
-
throw new Error('Claude client not initialized');
|
|
328
|
-
}
|
|
329
|
-
// Simulate interactive workflow processing
|
|
330
|
-
if (input.toLowerCase().includes('deploy') && context?.interactive) {
|
|
331
|
-
return {
|
|
332
|
-
phase: 'Planning',
|
|
333
|
-
questions: ['What type of database do you need?']
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
if (context?.responses) {
|
|
337
|
-
return {
|
|
338
|
-
phase: 'Validation',
|
|
339
|
-
nextSteps: ['Review generated manifest']
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
// Default response
|
|
343
|
-
return {
|
|
344
|
-
phase: 'Discovery',
|
|
345
|
-
suggestions: ['Start by exploring your cluster resources']
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Analyze user intent for clarification opportunities
|
|
350
|
-
*
|
|
351
|
-
* @param intent User's deployment intent
|
|
352
|
-
* @param organizationalPatterns Available organizational patterns context
|
|
353
|
-
* @returns Analysis result with clarification opportunities
|
|
354
|
-
*/
|
|
355
|
-
async analyzeIntentForClarification(intent, organizationalPatterns = '') {
|
|
356
|
-
if (!this.client && !this.isTestKey()) {
|
|
357
|
-
throw new Error('Claude client not initialized');
|
|
358
|
-
}
|
|
359
|
-
try {
|
|
360
|
-
// Load intent analysis prompt template
|
|
361
|
-
const analysisPrompt = (0, shared_prompt_loader_1.loadPrompt)('intent-analysis', {
|
|
362
|
-
intent,
|
|
363
|
-
organizational_patterns: organizationalPatterns || 'No specific organizational patterns available'
|
|
364
|
-
});
|
|
365
|
-
// Send to Claude for analysis
|
|
366
|
-
const response = await this.sendMessage(analysisPrompt, 'intent-analysis');
|
|
367
|
-
// Parse JSON response with robust error handling
|
|
368
|
-
let jsonContent = response.content;
|
|
369
|
-
// Try to find JSON object wrapped in code blocks
|
|
370
|
-
const codeBlockMatch = response.content.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/);
|
|
371
|
-
if (codeBlockMatch) {
|
|
372
|
-
jsonContent = codeBlockMatch[1];
|
|
373
|
-
}
|
|
374
|
-
else {
|
|
375
|
-
// Try to find JSON object that starts with { and find the matching closing }
|
|
376
|
-
const jsonMatch = response.content.match(/\{[\s\S]*\}/);
|
|
377
|
-
if (jsonMatch) {
|
|
378
|
-
jsonContent = jsonMatch[0];
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
// Parse the JSON
|
|
382
|
-
const analysisResult = JSON.parse(jsonContent);
|
|
383
|
-
// Validate the response structure
|
|
384
|
-
if (!analysisResult.clarificationOpportunities || !Array.isArray(analysisResult.clarificationOpportunities)) {
|
|
385
|
-
throw new Error('Invalid analysis result structure: missing clarificationOpportunities array');
|
|
386
|
-
}
|
|
387
|
-
if (!analysisResult.overallAssessment || !analysisResult.intentQuality) {
|
|
388
|
-
throw new Error('Invalid analysis result structure: missing overallAssessment or intentQuality');
|
|
389
|
-
}
|
|
390
|
-
return analysisResult;
|
|
391
|
-
}
|
|
392
|
-
catch (error) {
|
|
393
|
-
// If parsing fails or API call fails, return a fallback minimal analysis
|
|
394
|
-
console.warn('Intent analysis failed, returning minimal analysis:', error);
|
|
395
|
-
return {
|
|
396
|
-
clarificationOpportunities: [],
|
|
397
|
-
overallAssessment: {
|
|
398
|
-
enhancementPotential: 'LOW',
|
|
399
|
-
primaryGaps: [],
|
|
400
|
-
recommendedFocus: 'Proceed with original intent - analysis unavailable'
|
|
401
|
-
},
|
|
402
|
-
intentQuality: {
|
|
403
|
-
currentSpecificity: 'Unable to analyze - using original intent',
|
|
404
|
-
strengthAreas: ['User provided clear deployment intent'],
|
|
405
|
-
improvementAreas: []
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
isInitialized() {
|
|
411
|
-
return this.client !== null;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
exports.ClaudeIntegration = ClaudeIntegration;
|