@vfarcic/dot-ai 0.192.0 → 0.194.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 (105) hide show
  1. package/README.md +6 -6
  2. package/dist/core/agent-display.d.ts +2 -4
  3. package/dist/core/agent-display.d.ts.map +1 -1
  4. package/dist/core/agent-display.js +4 -12
  5. package/dist/core/base-vector-service.d.ts +6 -0
  6. package/dist/core/base-vector-service.d.ts.map +1 -1
  7. package/dist/core/base-vector-service.js +18 -8
  8. package/dist/core/capabilities.d.ts +12 -0
  9. package/dist/core/capabilities.d.ts.map +1 -1
  10. package/dist/core/capability-operations.d.ts +3 -0
  11. package/dist/core/capability-operations.d.ts.map +1 -1
  12. package/dist/core/capability-operations.js +88 -5
  13. package/dist/core/capability-scan-workflow.d.ts +35 -5
  14. package/dist/core/capability-scan-workflow.d.ts.map +1 -1
  15. package/dist/core/capability-scan-workflow.js +169 -145
  16. package/dist/core/capability-vector-service.d.ts +11 -2
  17. package/dist/core/capability-vector-service.d.ts.map +1 -1
  18. package/dist/core/capability-vector-service.js +50 -0
  19. package/dist/core/discovery.d.ts +34 -0
  20. package/dist/core/discovery.d.ts.map +1 -1
  21. package/dist/core/discovery.js +105 -19
  22. package/dist/core/index.d.ts +0 -1
  23. package/dist/core/index.d.ts.map +1 -1
  24. package/dist/core/index.js +1 -6
  25. package/dist/core/kubectl-tools.d.ts +5 -0
  26. package/dist/core/kubectl-tools.d.ts.map +1 -1
  27. package/dist/core/kubectl-tools.js +74 -2
  28. package/dist/core/kubernetes-utils.d.ts +1 -0
  29. package/dist/core/kubernetes-utils.d.ts.map +1 -1
  30. package/dist/core/kubernetes-utils.js +92 -49
  31. package/dist/core/packaging.d.ts.map +1 -1
  32. package/dist/core/packaging.js +1 -0
  33. package/dist/core/resource-tools.d.ts +163 -1
  34. package/dist/core/resource-tools.d.ts.map +1 -1
  35. package/dist/core/resource-tools.js +343 -23
  36. package/dist/core/resource-vector-service.d.ts +17 -0
  37. package/dist/core/resource-vector-service.d.ts.map +1 -1
  38. package/dist/core/resource-vector-service.js +67 -3
  39. package/dist/core/telemetry/client.d.ts +16 -0
  40. package/dist/core/telemetry/client.d.ts.map +1 -0
  41. package/dist/core/telemetry/client.js +293 -0
  42. package/dist/core/telemetry/config.d.ts +12 -0
  43. package/dist/core/telemetry/config.d.ts.map +1 -0
  44. package/dist/core/telemetry/config.js +130 -0
  45. package/dist/core/telemetry/index.d.ts +30 -0
  46. package/dist/core/telemetry/index.d.ts.map +1 -0
  47. package/dist/core/telemetry/index.js +49 -0
  48. package/dist/core/telemetry/types.d.ts +125 -0
  49. package/dist/core/telemetry/types.d.ts.map +1 -0
  50. package/dist/core/telemetry/types.js +7 -0
  51. package/dist/core/tracing/index.d.ts +1 -1
  52. package/dist/core/tracing/index.d.ts.map +1 -1
  53. package/dist/core/tracing/tool-tracing.d.ts +11 -2
  54. package/dist/core/tracing/tool-tracing.d.ts.map +1 -1
  55. package/dist/core/tracing/tool-tracing.js +17 -3
  56. package/dist/core/vector-db-service.d.ts +7 -0
  57. package/dist/core/vector-db-service.d.ts.map +1 -1
  58. package/dist/core/vector-db-service.js +165 -61
  59. package/dist/core/visualization.d.ts +16 -1
  60. package/dist/core/visualization.d.ts.map +1 -1
  61. package/dist/core/visualization.js +64 -1
  62. package/dist/interfaces/mcp.d.ts +6 -0
  63. package/dist/interfaces/mcp.d.ts.map +1 -1
  64. package/dist/interfaces/mcp.js +36 -7
  65. package/dist/interfaces/rest-api.d.ts +63 -2
  66. package/dist/interfaces/rest-api.d.ts.map +1 -1
  67. package/dist/interfaces/rest-api.js +611 -51
  68. package/dist/mcp/server.js +55 -9
  69. package/dist/tools/answer-question.d.ts.map +1 -1
  70. package/dist/tools/answer-question.js +18 -0
  71. package/dist/tools/choose-solution.d.ts.map +1 -1
  72. package/dist/tools/choose-solution.js +22 -1
  73. package/dist/tools/deploy-manifests.d.ts.map +1 -1
  74. package/dist/tools/deploy-manifests.js +16 -2
  75. package/dist/tools/generate-manifests.d.ts.map +1 -1
  76. package/dist/tools/generate-manifests.js +12 -18
  77. package/dist/tools/operate.d.ts.map +1 -1
  78. package/dist/tools/operate.js +3 -11
  79. package/dist/tools/organizational-data.d.ts +1 -1
  80. package/dist/tools/organizational-data.d.ts.map +1 -1
  81. package/dist/tools/organizational-data.js +8 -17
  82. package/dist/tools/project-setup.d.ts.map +1 -1
  83. package/dist/tools/project-setup.js +5 -18
  84. package/dist/tools/query.d.ts +2 -11
  85. package/dist/tools/query.d.ts.map +1 -1
  86. package/dist/tools/query.js +63 -44
  87. package/dist/tools/recommend.d.ts +18 -1
  88. package/dist/tools/recommend.d.ts.map +1 -1
  89. package/dist/tools/recommend.js +44 -10
  90. package/dist/tools/remediate.d.ts.map +1 -1
  91. package/dist/tools/remediate.js +2 -24
  92. package/dist/tools/version.d.ts.map +1 -1
  93. package/dist/tools/version.js +4 -7
  94. package/package.json +2 -1
  95. package/prompts/partials/query-simple-output.md +11 -0
  96. package/prompts/partials/visualization-output.md +93 -0
  97. package/prompts/query-system.md +8 -12
  98. package/prompts/resource-selection.md +4 -0
  99. package/prompts/visualize.md +1 -68
  100. package/scripts/dot-ai.nu +1 -0
  101. package/scripts/reset-sync-and-scan-test-cluster.sh +120 -0
  102. package/shared-prompts/prd-create.md +1 -1
  103. package/dist/core/feedback.d.ts +0 -43
  104. package/dist/core/feedback.d.ts.map +0 -1
  105. package/dist/core/feedback.js +0 -98
@@ -6,6 +6,7 @@
6
6
  * specification, processing mode selection, and the actual scanning process
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.scanSingleResource = scanSingleResource;
9
10
  exports.handleResourceSelection = handleResourceSelection;
10
11
  exports.handleResourceSpecification = handleResourceSpecification;
11
12
  exports.handleScanning = handleScanning;
@@ -13,24 +14,126 @@ const discovery_1 = require("./discovery");
13
14
  const capabilities_1 = require("./capabilities");
14
15
  const ai_provider_factory_1 = require("./ai-provider-factory");
15
16
  /**
16
- * Create user-friendly error message for resource definition failures
17
+ * Scan a single resource - fetches all data, runs AI inference, stores to DB
18
+ * This is the core function that both full scan and targeted scan call for each resource.
17
19
  */
18
- function createResourceDefinitionErrorMessage(resourceName, error) {
19
- const errorMessage = error instanceof Error ? error.message : String(error);
20
- let userFriendlyMessage = `Cannot analyze resource '${resourceName}': `;
21
- if (errorMessage.includes('not found') || errorMessage.includes('NotFound')) {
22
- userFriendlyMessage += `Resource does not exist in cluster. Please ensure the CRD is installed.`;
23
- }
24
- else if (errorMessage.includes('connection refused') || errorMessage.includes('timeout')) {
25
- userFriendlyMessage += `Cannot connect to Kubernetes cluster. Please check cluster connectivity.`;
26
- }
27
- else if (errorMessage.includes('forbidden') || errorMessage.includes('Forbidden')) {
28
- userFriendlyMessage += `Insufficient permissions to read resource definitions. Please check RBAC settings.`;
20
+ async function scanSingleResource(resourceName, discovery, engine, capabilityService, logger, requestId, interactionId) {
21
+ try {
22
+ // Step 1: Get resource metadata (including printerColumns for CRDs)
23
+ let metadata;
24
+ if (resourceName.includes('.')) {
25
+ // This is a CRD - fetch CRD data to get metadata including printerColumns
26
+ const dotIndex = resourceName.indexOf('.');
27
+ const kind = resourceName.substring(0, dotIndex);
28
+ const group = resourceName.substring(dotIndex + 1);
29
+ // Try common plural patterns to find CRD
30
+ const pluralGuesses = [
31
+ kind.toLowerCase() + 's',
32
+ kind.toLowerCase().endsWith('y') ? kind.toLowerCase().slice(0, -1) + 'ies' : null,
33
+ kind.toLowerCase().endsWith('s') ? kind.toLowerCase() + 'es' : null
34
+ ].filter(Boolean);
35
+ for (const plural of pluralGuesses) {
36
+ try {
37
+ const crdName = `${plural}.${group}`;
38
+ const crdData = await discovery.getCRDData(crdName);
39
+ const storageVersion = crdData.versions.find(v => v.storage) || crdData.versions[0];
40
+ metadata = {
41
+ apiVersion: `${crdData.group}/${crdData.version}`,
42
+ version: crdData.version,
43
+ group: crdData.group,
44
+ resourcePlural: crdData.resourcePlural,
45
+ printerColumns: storageVersion?.additionalPrinterColumns
46
+ };
47
+ break;
48
+ }
49
+ catch {
50
+ // Try next plural form
51
+ }
52
+ }
53
+ }
54
+ // Step 2: Get resource definition via kubectl explain
55
+ let resourceDefinition;
56
+ try {
57
+ resourceDefinition = await discovery.explainResource(resourceName);
58
+ }
59
+ catch (explainError) {
60
+ // If explain fails and resource has a dot, try with just the Kind
61
+ if (resourceName.includes('.')) {
62
+ const resourceKind = resourceName.split('.')[0];
63
+ resourceDefinition = await discovery.explainResource(resourceKind);
64
+ }
65
+ else {
66
+ throw explainError;
67
+ }
68
+ }
69
+ // If no CRD metadata, parse from kubectl explain output
70
+ if (!metadata && resourceDefinition) {
71
+ const lines = resourceDefinition.split('\n');
72
+ const groupLine = lines.find((line) => line.startsWith('GROUP:'));
73
+ const versionLine = lines.find((line) => line.startsWith('VERSION:'));
74
+ if (versionLine) {
75
+ const group = groupLine ? groupLine.replace('GROUP:', '').trim() : '';
76
+ const version = versionLine.replace('VERSION:', '').trim();
77
+ const apiVersion = group ? `${group}/${version}` : version;
78
+ // For core resources, derive plural from kind
79
+ const kind = resourceName.includes('.') ? resourceName.split('.')[0] : resourceName;
80
+ const resourcePlural = kind.toLowerCase() + 's';
81
+ metadata = { apiVersion, version, group, resourcePlural };
82
+ }
83
+ }
84
+ // Step 3: Run AI inference
85
+ const capability = await engine.inferCapabilities(resourceName, resourceDefinition, interactionId, metadata?.apiVersion, metadata?.version, metadata?.group);
86
+ const capabilityId = capabilities_1.CapabilityInferenceEngine.generateCapabilityId(resourceName);
87
+ // Step 4: Set printer columns
88
+ const nameColumn = {
89
+ name: 'Name',
90
+ type: 'string',
91
+ jsonPath: '.metadata.name',
92
+ description: 'Resource name',
93
+ priority: 0
94
+ };
95
+ if (metadata?.printerColumns && metadata.printerColumns.length > 0) {
96
+ // Use printer columns from CRD metadata (includes jsonPath)
97
+ capability.printerColumns = [nameColumn, ...metadata.printerColumns];
98
+ }
99
+ else if (metadata?.apiVersion && metadata?.resourcePlural) {
100
+ // Fall back to Table API for core resources
101
+ try {
102
+ const printerColumns = await discovery.getPrinterColumns(metadata.resourcePlural, metadata.apiVersion);
103
+ capability.printerColumns = printerColumns;
104
+ }
105
+ catch (printerError) {
106
+ logger.warn(`Failed to fetch printer columns for ${resourceName}`, {
107
+ requestId,
108
+ resource: resourceName,
109
+ error: printerError instanceof Error ? printerError.message : String(printerError)
110
+ });
111
+ }
112
+ }
113
+ // Step 5: Store to DB
114
+ await capabilityService.storeCapability(capability);
115
+ return {
116
+ success: true,
117
+ resource: resourceName,
118
+ id: capabilityId,
119
+ capabilities: capability.capabilities,
120
+ providers: capability.providers,
121
+ complexity: capability.complexity,
122
+ confidence: capability.confidence
123
+ };
29
124
  }
30
- else {
31
- userFriendlyMessage += `${errorMessage}`;
125
+ catch (error) {
126
+ const errorMessage = error instanceof Error ? error.message : String(error);
127
+ logger.error(`Failed to scan resource ${resourceName}`, error, {
128
+ requestId,
129
+ resource: resourceName
130
+ });
131
+ return {
132
+ success: false,
133
+ resource: resourceName,
134
+ error: errorMessage
135
+ };
32
136
  }
33
- return userFriendlyMessage;
34
137
  }
35
138
  /**
36
139
  * Handle resource selection step
@@ -200,11 +303,17 @@ async function handleResourceSpecification(session, args, logger, requestId, cap
200
303
  }
201
304
  };
202
305
  }
203
- // Transition directly to scanning (auto mode only - manual mode removed)
306
+ logger.info('Resource specification received', {
307
+ requestId,
308
+ sessionId: session.sessionId,
309
+ resourceCount: resources.length,
310
+ resources
311
+ });
312
+ // Transition directly to scanning - scanSingleResource will fetch metadata for each
204
313
  transitionCapabilitySession(session, 'scanning', {
205
314
  selectedResources: resources,
206
315
  resourceList: args.resourceList,
207
- currentResourceIndex: 0 // Start with first resource
316
+ currentResourceIndex: 0
208
317
  }, args);
209
318
  // Begin actual capability scanning and return completion summary
210
319
  return await handleScanningFn(session, { ...args, response: undefined }, logger, requestId, capabilityService, parseNumericResponse, transitionCapabilitySession, cleanupCapabilitySession, createCapabilityScanCompletionResponse);
@@ -247,19 +356,21 @@ async function handleScanning(session, args, logger, requestId, capabilityServic
247
356
  // For 'all' mode, discover actual cluster resources first
248
357
  try {
249
358
  logger.info('Discovering all cluster resources for capability scanning', { requestId, sessionId: session.sessionId });
250
- // Import discovery engine
251
359
  const discovery = new discovery_1.KubernetesDiscovery();
252
360
  await discovery.connect();
253
361
  // Discover all available resources
254
362
  const resourceMap = await discovery.discoverResources();
255
363
  const allResources = [...resourceMap.resources, ...resourceMap.custom];
256
- // Extract resource names AND preserve metadata for capability analysis
364
+ // Extract resource names only - scanSingleResource will fetch metadata for each
257
365
  const discoveredResourceNames = [];
258
- const resourceMetadata = {};
259
366
  for (const resource of allResources) {
260
367
  let resourceName = 'unknown-resource';
261
- // For CRDs (custom resources), prioritize full name format
262
- if (resource.name && resource.name.includes('.')) {
368
+ // For CRDs (custom resources), use Kind.group format
369
+ if ('kind' in resource && resource.kind && 'group' in resource && resource.group) {
370
+ resourceName = `${resource.kind}.${resource.group}`;
371
+ }
372
+ // For CRDs with name format "plural.group"
373
+ else if (resource.name && resource.name.includes('.')) {
263
374
  resourceName = resource.name;
264
375
  }
265
376
  // For standard resources, use kind
@@ -272,36 +383,13 @@ async function handleScanning(session, args, logger, requestId, capabilityServic
272
383
  }
273
384
  if (resourceName !== 'unknown-resource') {
274
385
  discoveredResourceNames.push(resourceName);
275
- // Store apiVersion metadata for later use
276
- // Handle both EnhancedResource (has apiVersion) and EnhancedCRD (has group+version)
277
- let apiVersion = '';
278
- let version = '';
279
- let group = '';
280
- if ('apiVersion' in resource) {
281
- // EnhancedResource type
282
- apiVersion = resource.apiVersion || '';
283
- version = apiVersion.includes('/') ? apiVersion.split('/')[1] : apiVersion;
284
- group = resource.group || '';
285
- }
286
- else {
287
- // EnhancedCRD type - construct apiVersion from group and version
288
- group = resource.group || '';
289
- version = resource.version || '';
290
- apiVersion = group ? `${group}/${version}` : version;
291
- }
292
- resourceMetadata[resourceName] = {
293
- apiVersion,
294
- version,
295
- group
296
- };
297
386
  }
298
387
  }
299
388
  logger.info('Discovered cluster resources for capability scanning', {
300
389
  requestId,
301
390
  sessionId: session.sessionId,
302
391
  totalDiscovered: discoveredResourceNames.length,
303
- sampleResources: discoveredResourceNames.slice(0, 5),
304
- metadataPreserved: Object.keys(resourceMetadata).length
392
+ sampleResources: discoveredResourceNames.slice(0, 5)
305
393
  });
306
394
  if (discoveredResourceNames.length === 0) {
307
395
  return {
@@ -315,10 +403,9 @@ async function handleScanning(session, args, logger, requestId, capabilityServic
315
403
  }
316
404
  };
317
405
  }
318
- // Update session with discovered resources AND metadata
406
+ // Update session with discovered resources
319
407
  transitionCapabilitySession(session, 'scanning', {
320
408
  selectedResources: discoveredResourceNames,
321
- resourceMetadata: resourceMetadata,
322
409
  currentResourceIndex: 0
323
410
  }, args);
324
411
  // Fall through to batch processing with discovered resources
@@ -396,127 +483,64 @@ async function handleScanning(session, args, logger, requestId, capabilityServic
396
483
  progress: progressData
397
484
  }, args);
398
485
  };
399
- // Setup kubectl access for getting complete resource definitions
400
- let discovery;
486
+ // Setup kubectl access
487
+ const discovery = new discovery_1.KubernetesDiscovery();
401
488
  try {
402
- discovery = new discovery_1.KubernetesDiscovery();
403
489
  await discovery.connect();
404
- logger.info('Connected to Kubernetes for batch resource definition retrieval', {
490
+ logger.info('Connected to Kubernetes for capability scanning', {
405
491
  requestId,
406
492
  sessionId: session.sessionId
407
493
  });
408
494
  }
409
495
  catch (error) {
410
- logger.warn('Could not connect to Kubernetes for batch processing, falling back to name-based inference', {
411
- requestId,
412
- sessionId: session.sessionId,
413
- error: error instanceof Error ? error.message : String(error)
414
- });
496
+ return {
497
+ success: false,
498
+ operation: 'scan',
499
+ dataType: 'capabilities',
500
+ error: {
501
+ message: 'Could not connect to Kubernetes cluster',
502
+ details: error instanceof Error ? error.message : String(error),
503
+ sessionId: session.sessionId
504
+ }
505
+ };
415
506
  }
416
- // Process each resource in the batch with progress tracking
507
+ // Process each resource using scanSingleResource
417
508
  for (let i = 0; i < resources.length; i++) {
418
509
  const currentResource = resources[i];
419
- // Get complete resource definition for this resource
420
- let currentResourceDefinition;
421
- if (discovery) {
422
- try {
423
- // Try kubectl explain with full name first (works for CRDs and core resources)
424
- try {
425
- currentResourceDefinition = await discovery.explainResource(currentResource);
426
- }
427
- catch (explainError) {
428
- // If explain fails and resource has a dot (like Deployment.apps), try with just the Kind
429
- if (currentResource.includes('.')) {
430
- const resourceKind = currentResource.split('.')[0];
431
- logger.info(`kubectl explain failed for ${currentResource}, attempting with Kind only: ${resourceKind}`, {
432
- requestId,
433
- sessionId: session.sessionId,
434
- resource: currentResource,
435
- resourceKind
436
- });
437
- currentResourceDefinition = await discovery.explainResource(resourceKind);
438
- }
439
- else {
440
- // Re-throw explain error for resources without dots
441
- throw explainError;
442
- }
443
- }
444
- }
445
- catch (error) {
446
- logger.error(`Failed to get resource definition for ${currentResource}`, error, {
447
- requestId,
448
- sessionId: session.sessionId,
449
- resource: currentResource
450
- });
451
- // Add to errors array and skip processing this resource
452
- errors.push({
453
- resource: currentResource,
454
- error: createResourceDefinitionErrorMessage(currentResource, error),
455
- timestamp: new Date().toISOString()
456
- });
457
- // Skip processing this resource
458
- continue;
459
- }
460
- }
461
510
  // Update progress before processing
462
511
  updateProgress(i + 1, currentResource, processedResults.length, errors.length, errors);
463
- try {
464
- logger.info(`Processing resource ${i + 1}/${totalResources}`, {
465
- requestId,
466
- sessionId: session.sessionId,
467
- resource: currentResource,
468
- percentage: Math.round(((i + 1) / totalResources) * 100)
469
- });
470
- // Get metadata for this resource - first try session metadata, then parse from kubectl explain
471
- let metadata = session.resourceMetadata?.[currentResource];
472
- // If no session metadata and we have resource definition, parse from kubectl explain output
473
- if (!metadata && currentResourceDefinition) {
474
- const lines = currentResourceDefinition.split('\n');
475
- const groupLine = lines.find((line) => line.startsWith('GROUP:'));
476
- const versionLine = lines.find((line) => line.startsWith('VERSION:'));
477
- // Extract metadata if version is found (group is optional for core resources)
478
- if (versionLine) {
479
- const group = groupLine ? groupLine.replace('GROUP:', '').trim() : '';
480
- const version = versionLine.replace('VERSION:', '').trim();
481
- const apiVersion = group ? `${group}/${version}` : version;
482
- metadata = { apiVersion, version, group };
483
- }
484
- }
485
- const capability = await engine.inferCapabilities(currentResource, currentResourceDefinition, args.interaction_id, metadata?.apiVersion, metadata?.version, metadata?.group);
486
- const capabilityId = capabilities_1.CapabilityInferenceEngine.generateCapabilityId(currentResource);
487
- // Store capability in Vector DB
488
- await capabilityService.storeCapability(capability);
512
+ logger.info(`Processing resource ${i + 1}/${totalResources}`, {
513
+ requestId,
514
+ sessionId: session.sessionId,
515
+ resource: currentResource,
516
+ percentage: Math.round(((i + 1) / totalResources) * 100)
517
+ });
518
+ // Call the shared single-resource scan function
519
+ const result = await scanSingleResource(currentResource, discovery, engine, capabilityService, logger, requestId, args.interaction_id);
520
+ if (result.success) {
489
521
  processedResults.push({
490
- resource: currentResource,
491
- id: capabilityId,
492
- capabilities: capability.capabilities,
493
- providers: capability.providers,
494
- complexity: capability.complexity,
495
- confidence: capability.confidence
522
+ resource: result.resource,
523
+ id: result.id,
524
+ capabilities: result.capabilities,
525
+ providers: result.providers,
526
+ complexity: result.complexity,
527
+ confidence: result.confidence
496
528
  });
497
529
  logger.info(`Successfully processed resource ${i + 1}/${totalResources}`, {
498
530
  requestId,
499
531
  sessionId: session.sessionId,
500
532
  resource: currentResource,
501
- capabilitiesFound: capability.capabilities.length,
533
+ capabilitiesFound: result.capabilities?.length || 0,
502
534
  percentage: Math.round(((i + 1) / totalResources) * 100)
503
535
  });
504
536
  }
505
- catch (error) {
506
- const errorMessage = error instanceof Error ? error.message : String(error);
507
- const errorDetail = {
508
- resource: currentResource,
509
- error: errorMessage,
537
+ else {
538
+ errors.push({
539
+ resource: result.resource,
540
+ error: result.error,
510
541
  index: i + 1,
511
542
  timestamp: new Date().toISOString()
512
- };
513
- logger.error(`Failed to process resource ${i + 1}/${totalResources}`, error, {
514
- requestId,
515
- sessionId: session.sessionId,
516
- resource: currentResource,
517
- percentage: Math.round(((i + 1) / totalResources) * 100)
518
543
  });
519
- errors.push(errorDetail);
520
544
  }
521
545
  }
522
546
  // Final progress update - mark as completed
@@ -7,8 +7,8 @@
7
7
  import { BaseVectorService, BaseSearchOptions, BaseSearchResult } from './base-vector-service';
8
8
  import { VectorDBService } from './vector-db-service';
9
9
  import { EmbeddingService } from './embedding-service';
10
- import { ResourceCapability } from './capabilities';
11
- export type { ResourceCapability };
10
+ import { ResourceCapability, PrinterColumn } from './capabilities';
11
+ export type { ResourceCapability, PrinterColumn };
12
12
  export interface CapabilitySearchOptions extends BaseSearchOptions {
13
13
  complexityFilter?: 'low' | 'medium' | 'high';
14
14
  providerFilter?: string[];
@@ -47,6 +47,15 @@ export declare class CapabilityVectorService extends BaseVectorService<ResourceC
47
47
  * Used by MCP operations with IDs from list/search results
48
48
  */
49
49
  getCapability(id: string): Promise<ResourceCapability | null>;
50
+ /**
51
+ * Get capability by kind and apiVersion
52
+ * Used for JSON format lookup from dashboard UI
53
+ *
54
+ * @param kind - Resource kind (e.g., "Deployment", "Cluster")
55
+ * @param apiVersion - Full apiVersion (e.g., "apps/v1", "postgresql.cnpg.io/v1")
56
+ * @returns Matching capability or null if not found
57
+ */
58
+ getCapabilityByKindApiVersion(kind: string, apiVersion: string): Promise<ResourceCapability | null>;
50
59
  /**
51
60
  * Delete capability by resource name
52
61
  */
@@ -1 +1 @@
1
- {"version":3,"file":"capability-vector-service.d.ts","sourceRoot":"","sources":["../../src/core/capability-vector-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAA6B,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAG/E,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC7C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,iBAAiB,CAAC,kBAAkB,CAAC;gBAEpE,cAAc,GAAE,MAAuB,EAAE,QAAQ,CAAC,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAIpH;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM;IAYlE;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM;IAI3D;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAiB5E;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,kBAAkB;IAiBzE;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE;;OAEG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,EAAE,CAAC;IAoBlD;;;OAGG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAInE;;OAEG;IACG,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3D;;OAEG;IACG,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;IACG,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAIvE;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CAK9C"}
1
+ {"version":3,"file":"capability-vector-service.d.ts","sourceRoot":"","sources":["../../src/core/capability-vector-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAA6B,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG9F,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAElD,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC7C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,iBAAiB,CAAC,kBAAkB,CAAC;gBAEpE,cAAc,GAAE,MAAuB,EAAE,QAAQ,CAAC,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE,gBAAgB;IAIpH;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM;IAYlE;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM;IAI3D;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAkB5E;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,kBAAkB;IAkBzE;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE;;OAEG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,EAAE,CAAC;IAoBlD;;;OAGG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAInE;;;;;;;OAOG;IACG,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAwCzG;;OAEG;IACG,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3D;;OAEG;IACG,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;IACG,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAIvE;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CAK9C"}
@@ -51,6 +51,7 @@ class CapabilityVectorService extends base_vector_service_1.BaseVectorService {
51
51
  complexity: capability.complexity,
52
52
  description: capability.description,
53
53
  useCase: capability.useCase,
54
+ printerColumns: capability.printerColumns,
54
55
  confidence: capability.confidence,
55
56
  analyzedAt: capability.analyzedAt
56
57
  };
@@ -70,6 +71,7 @@ class CapabilityVectorService extends base_vector_service_1.BaseVectorService {
70
71
  complexity: payload.complexity || 'medium',
71
72
  description: payload.description || '',
72
73
  useCase: payload.useCase || '',
74
+ printerColumns: payload.printerColumns,
73
75
  confidence: payload.confidence || 0,
74
76
  analyzedAt: payload.analyzedAt || new Date().toISOString()
75
77
  };
@@ -102,6 +104,54 @@ class CapabilityVectorService extends base_vector_service_1.BaseVectorService {
102
104
  async getCapability(id) {
103
105
  return await this.getData(id);
104
106
  }
107
+ /**
108
+ * Get capability by kind and apiVersion
109
+ * Used for JSON format lookup from dashboard UI
110
+ *
111
+ * @param kind - Resource kind (e.g., "Deployment", "Cluster")
112
+ * @param apiVersion - Full apiVersion (e.g., "apps/v1", "postgresql.cnpg.io/v1")
113
+ * @returns Matching capability or null if not found
114
+ */
115
+ async getCapabilityByKindApiVersion(kind, apiVersion) {
116
+ // Build Qdrant filter for exact apiVersion match
117
+ const filter = {
118
+ must: [
119
+ { key: 'apiVersion', match: { value: apiVersion } }
120
+ ]
121
+ };
122
+ const results = await this.queryWithFilter(filter, 100);
123
+ if (results.length === 0) {
124
+ return null;
125
+ }
126
+ // Find matching capability by kind
127
+ // For standard resources: resourceName === kind (case insensitive)
128
+ // For CRDs: resourceName matches Kind.group or plural.group pattern
129
+ const kindLower = kind.toLowerCase();
130
+ const match = results.find(cap => {
131
+ const resourceNameLower = cap.resourceName.toLowerCase();
132
+ // Exact match
133
+ if (resourceNameLower === kindLower)
134
+ return true;
135
+ // Pluralized exact match (e.g., "deployment" -> "deployments")
136
+ if (resourceNameLower === kindLower + 's' || resourceNameLower === kindLower + 'es')
137
+ return true;
138
+ // CRD format: Kind.group (e.g., "deployment" -> "deployment.apps")
139
+ // Must match kind followed by a dot to avoid false positives like "cluster" matching "clusterroles"
140
+ if (resourceNameLower.startsWith(kindLower + '.'))
141
+ return true;
142
+ // CRD format: plural.group (e.g., "cluster" -> "clusters.devopstoolkit.live")
143
+ if (resourceNameLower.startsWith(kindLower + 's.') || resourceNameLower.startsWith(kindLower + 'es.'))
144
+ return true;
145
+ // Handle -y -> -ies pluralization (e.g., "policy" -> "policies.group")
146
+ if (kindLower.endsWith('y')) {
147
+ const stem = kindLower.slice(0, -1);
148
+ if (resourceNameLower === stem + 'ies' || resourceNameLower.startsWith(stem + 'ies.'))
149
+ return true;
150
+ }
151
+ return false;
152
+ });
153
+ return match || null;
154
+ }
105
155
  /**
106
156
  * Delete capability by resource name
107
157
  */
@@ -20,11 +20,19 @@ export interface EnhancedCRD {
20
20
  version: string;
21
21
  kind: string;
22
22
  scope: 'Namespaced' | 'Cluster';
23
+ resourcePlural: string;
23
24
  versions: Array<{
24
25
  name: string;
25
26
  served: boolean;
26
27
  storage: boolean;
27
28
  schema?: any;
29
+ additionalPrinterColumns?: Array<{
30
+ name: string;
31
+ type: string;
32
+ jsonPath: string;
33
+ description?: string;
34
+ priority?: number;
35
+ }>;
28
36
  }>;
29
37
  schema?: any;
30
38
  }
@@ -141,6 +149,15 @@ export declare class KubernetesDiscovery {
141
149
  * Delegates to shared utility function
142
150
  */
143
151
  executeKubectl(args: string[], config?: KubectlConfig): Promise<string>;
152
+ /**
153
+ * Parse a raw CRD object into EnhancedCRD format
154
+ */
155
+ private parseCRDItem;
156
+ /**
157
+ * Fetch a single CRD by name with all metadata including printer columns
158
+ * This is the single source of truth for CRD data - used by both full and targeted scans
159
+ */
160
+ getCRDData(crdName: string): Promise<EnhancedCRD>;
144
161
  discoverCRDs(options?: {
145
162
  group?: string;
146
163
  }): Promise<EnhancedCRD[]>;
@@ -156,6 +173,23 @@ export declare class KubernetesDiscovery {
156
173
  * @returns Cleaned YAML string suitable for AI prompts
157
174
  */
158
175
  getCRDDefinition(crdName: string): Promise<string>;
176
+ /**
177
+ * Get printer columns for a resource type via Kubernetes Table API
178
+ * Works for both CRDs and core Kubernetes resources
179
+ * For CRDs, also fetches jsonPath from the CRD spec (not available in Table API)
180
+ *
181
+ * @param resourcePlural - Plural name of the resource (e.g., 'deployments', 'pods', 'sqls')
182
+ * @param apiVersion - Full API version (e.g., 'apps/v1', 'v1', 'devopstoolkit.live/v1beta1')
183
+ * @returns Array of printer column definitions (may be empty if resource has no custom columns)
184
+ * @throws Error on API/auth failures
185
+ */
186
+ getPrinterColumns(resourcePlural: string, apiVersion: string): Promise<Array<{
187
+ name: string;
188
+ type: string;
189
+ jsonPath: string;
190
+ description?: string;
191
+ priority?: number;
192
+ }>>;
159
193
  fingerprintCluster(): Promise<ClusterFingerprint>;
160
194
  private getResourceCounts;
161
195
  private getNetworkingInfo;
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/core/discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/core/discovery.ts"],"names":[],"mappings":"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"}