@vfarcic/dot-ai 0.195.0 → 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 (114) hide show
  1. package/README.md +2 -7
  2. package/dist/core/capability-scan-workflow.d.ts +4 -3
  3. package/dist/core/capability-scan-workflow.d.ts.map +1 -1
  4. package/dist/core/capability-scan-workflow.js +34 -39
  5. package/dist/core/circuit-breaker.d.ts +1 -0
  6. package/dist/core/circuit-breaker.d.ts.map +1 -1
  7. package/dist/core/circuit-breaker.js +11 -3
  8. package/dist/core/command-executor.d.ts +10 -1
  9. package/dist/core/command-executor.d.ts.map +1 -1
  10. package/dist/core/command-executor.js +63 -48
  11. package/dist/core/crd-availability.d.ts +6 -1
  12. package/dist/core/crd-availability.d.ts.map +1 -1
  13. package/dist/core/crd-availability.js +59 -49
  14. package/dist/core/deploy-operation.d.ts +17 -3
  15. package/dist/core/deploy-operation.d.ts.map +1 -1
  16. package/dist/core/deploy-operation.js +72 -21
  17. package/dist/core/discovery.d.ts +16 -43
  18. package/dist/core/discovery.d.ts.map +1 -1
  19. package/dist/core/discovery.js +128 -277
  20. package/dist/core/index.d.ts +10 -2
  21. package/dist/core/index.d.ts.map +1 -1
  22. package/dist/core/index.js +20 -9
  23. package/dist/core/pattern-operations.d.ts +3 -1
  24. package/dist/core/pattern-operations.d.ts.map +1 -1
  25. package/dist/core/pattern-operations.js +3 -2
  26. package/dist/core/plugin-client.d.ts +53 -0
  27. package/dist/core/plugin-client.d.ts.map +1 -0
  28. package/dist/core/plugin-client.js +148 -0
  29. package/dist/core/plugin-manager.d.ts +119 -0
  30. package/dist/core/plugin-manager.d.ts.map +1 -0
  31. package/dist/core/plugin-manager.js +366 -0
  32. package/dist/core/plugin-types.d.ts +100 -0
  33. package/dist/core/plugin-types.d.ts.map +1 -0
  34. package/dist/core/plugin-types.js +10 -0
  35. package/dist/core/policy-operations.d.ts +15 -7
  36. package/dist/core/policy-operations.d.ts.map +1 -1
  37. package/dist/core/policy-operations.js +59 -31
  38. package/dist/core/resource-tools.d.ts +2 -90
  39. package/dist/core/resource-tools.d.ts.map +1 -1
  40. package/dist/core/resource-tools.js +4 -178
  41. package/dist/core/schema.d.ts +18 -2
  42. package/dist/core/schema.d.ts.map +1 -1
  43. package/dist/core/schema.js +118 -16
  44. package/dist/core/telemetry/client.d.ts +7 -0
  45. package/dist/core/telemetry/client.d.ts.map +1 -1
  46. package/dist/core/telemetry/client.js +51 -51
  47. package/dist/core/telemetry/index.d.ts +1 -1
  48. package/dist/core/telemetry/index.d.ts.map +1 -1
  49. package/dist/core/telemetry/index.js +2 -1
  50. package/dist/core/telemetry/types.d.ts +1 -3
  51. package/dist/core/telemetry/types.d.ts.map +1 -1
  52. package/dist/core/tracing/index.d.ts +0 -1
  53. package/dist/core/tracing/index.d.ts.map +1 -1
  54. package/dist/core/tracing/index.js +1 -4
  55. package/dist/core/unified-creation-session.d.ts +6 -1
  56. package/dist/core/unified-creation-session.d.ts.map +1 -1
  57. package/dist/core/unified-creation-session.js +19 -11
  58. package/dist/interfaces/mcp.d.ts +8 -2
  59. package/dist/interfaces/mcp.d.ts.map +1 -1
  60. package/dist/interfaces/mcp.js +85 -34
  61. package/dist/interfaces/resource-sync-handler.d.ts.map +1 -1
  62. package/dist/interfaces/resource-sync-handler.js +37 -17
  63. package/dist/interfaces/rest-api.d.ts +4 -1
  64. package/dist/interfaces/rest-api.d.ts.map +1 -1
  65. package/dist/interfaces/rest-api.js +172 -49
  66. package/dist/mcp/server.js +39 -54
  67. package/dist/tools/deploy-manifests.d.ts +3 -1
  68. package/dist/tools/deploy-manifests.d.ts.map +1 -1
  69. package/dist/tools/deploy-manifests.js +112 -13
  70. package/dist/tools/generate-manifests.d.ts +3 -1
  71. package/dist/tools/generate-manifests.d.ts.map +1 -1
  72. package/dist/tools/generate-manifests.js +107 -33
  73. package/dist/tools/operate-analysis.d.ts +5 -1
  74. package/dist/tools/operate-analysis.d.ts.map +1 -1
  75. package/dist/tools/operate-analysis.js +37 -7
  76. package/dist/tools/operate-execution.d.ts +3 -1
  77. package/dist/tools/operate-execution.d.ts.map +1 -1
  78. package/dist/tools/operate-execution.js +6 -4
  79. package/dist/tools/operate.d.ts +7 -2
  80. package/dist/tools/operate.d.ts.map +1 -1
  81. package/dist/tools/operate.js +10 -6
  82. package/dist/tools/organizational-data.d.ts +3 -2
  83. package/dist/tools/organizational-data.d.ts.map +1 -1
  84. package/dist/tools/organizational-data.js +15 -13
  85. package/dist/tools/query.d.ts +5 -1
  86. package/dist/tools/query.d.ts.map +1 -1
  87. package/dist/tools/query.js +26 -18
  88. package/dist/tools/recommend.d.ts +3 -1
  89. package/dist/tools/recommend.d.ts.map +1 -1
  90. package/dist/tools/recommend.js +7 -7
  91. package/dist/tools/remediate.d.ts +5 -2
  92. package/dist/tools/remediate.d.ts.map +1 -1
  93. package/dist/tools/remediate.js +69 -20
  94. package/dist/tools/version.d.ts +20 -5
  95. package/dist/tools/version.d.ts.map +1 -1
  96. package/dist/tools/version.js +169 -161
  97. package/package.json +1 -1
  98. package/prompts/helm-generation.md +9 -0
  99. package/dist/core/cluster-utils.d.ts +0 -12
  100. package/dist/core/cluster-utils.d.ts.map +0 -1
  101. package/dist/core/cluster-utils.js +0 -27
  102. package/dist/core/helm-utils.d.ts +0 -66
  103. package/dist/core/helm-utils.d.ts.map +0 -1
  104. package/dist/core/helm-utils.js +0 -196
  105. package/dist/core/kubectl-tools.d.ts +0 -71
  106. package/dist/core/kubectl-tools.d.ts.map +0 -1
  107. package/dist/core/kubectl-tools.js +0 -546
  108. package/dist/core/kubernetes-utils.d.ts +0 -38
  109. package/dist/core/kubernetes-utils.d.ts.map +0 -1
  110. package/dist/core/kubernetes-utils.js +0 -288
  111. package/dist/core/tracing/k8s-tracing.d.ts +0 -57
  112. package/dist/core/tracing/k8s-tracing.d.ts.map +0 -1
  113. package/dist/core/tracing/k8s-tracing.js +0 -155
  114. package/scripts/toolhive.nu +0 -21
@@ -3,16 +3,63 @@
3
3
  * Deploy Manifests Tool - Apply Kubernetes manifests or execute Helm installations
4
4
  * Supports both capability-based solutions (kubectl apply) and Helm-based solutions (helm install)
5
5
  */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
6
39
  Object.defineProperty(exports, "__esModule", { value: true });
7
40
  exports.DEPLOYMANIFESTS_TOOL_INPUT_SCHEMA = exports.DEPLOYMANIFESTS_TOOL_DESCRIPTION = exports.DEPLOYMANIFESTS_TOOL_NAME = void 0;
8
41
  exports.handleDeployManifestsTool = handleDeployManifestsTool;
9
42
  const zod_1 = require("zod");
10
43
  const error_handling_1 = require("../core/error-handling");
11
44
  const deploy_operation_1 = require("../core/deploy-operation");
12
- const cluster_utils_1 = require("../core/cluster-utils");
13
45
  const generic_session_manager_1 = require("../core/generic-session-manager");
14
46
  const solution_utils_1 = require("../core/solution-utils");
15
- const helm_utils_1 = require("../core/helm-utils");
47
+ const fs = __importStar(require("fs"));
48
+ const path = __importStar(require("path"));
49
+ // PRD #343: Inline utilities (helm-utils.ts removed - all helm operations via plugin)
50
+ /**
51
+ * Get the path for Helm values file
52
+ */
53
+ function getHelmValuesPath(solutionId) {
54
+ const tmpDir = path.join(process.cwd(), 'tmp');
55
+ return path.join(tmpDir, `${solutionId}-values.yaml`);
56
+ }
57
+ /**
58
+ * Check if Helm values file exists for a solution
59
+ */
60
+ function helmValuesExist(solutionId) {
61
+ return fs.existsSync(getHelmValuesPath(solutionId));
62
+ }
16
63
  // Tool metadata for direct MCP registration
17
64
  exports.DEPLOYMANIFESTS_TOOL_NAME = 'deployManifests';
18
65
  exports.DEPLOYMANIFESTS_TOOL_DESCRIPTION = 'Deploy Kubernetes manifests from generated solution with kubectl apply --wait';
@@ -23,8 +70,9 @@ exports.DEPLOYMANIFESTS_TOOL_INPUT_SCHEMA = {
23
70
  };
24
71
  /**
25
72
  * Direct MCP tool handler for deployManifests functionality
73
+ * PRD #343: pluginManager required for kubectl operations
26
74
  */
27
- async function handleDeployManifestsTool(args, dotAI, logger, requestId) {
75
+ async function handleDeployManifestsTool(args, dotAI, logger, requestId, pluginManager) {
28
76
  return await error_handling_1.ErrorHandler.withErrorHandling(async () => {
29
77
  logger.debug('Handling deployManifests request', {
30
78
  requestId,
@@ -33,8 +81,6 @@ async function handleDeployManifestsTool(args, dotAI, logger, requestId) {
33
81
  });
34
82
  // Input validation is handled automatically by MCP SDK with Zod schema
35
83
  // args are already validated and typed when we reach this point
36
- // Ensure cluster connectivity before proceeding
37
- await (0, cluster_utils_1.ensureClusterConnection)(dotAI, logger, requestId, 'DeployManifestsTool');
38
84
  // Load solution session to determine solution type
39
85
  const sessionManager = new generic_session_manager_1.GenericSessionManager('sol');
40
86
  const session = sessionManager.getSession(args.solutionId);
@@ -63,20 +109,72 @@ async function handleDeployManifestsTool(args, dotAI, logger, requestId) {
63
109
  if (!releaseName) {
64
110
  throw new Error('Release name (name) is required for Helm deployment');
65
111
  }
66
- // Get values path if values file exists
67
- const valuesPath = (0, helm_utils_1.helmValuesExist)(args.solutionId)
68
- ? (0, helm_utils_1.getHelmValuesPath)(args.solutionId)
69
- : undefined;
70
- logger.info('Starting Helm deployment', {
112
+ // Get values content if values file exists
113
+ // PRD #343: Read values and pass to plugin (no file path to plugin)
114
+ let valuesYaml;
115
+ if (helmValuesExist(args.solutionId)) {
116
+ valuesYaml = fs.readFileSync(getHelmValuesPath(args.solutionId), 'utf8');
117
+ }
118
+ logger.info('Starting Helm deployment via plugin', {
71
119
  solutionId: args.solutionId,
72
120
  chart: `${chart.repositoryName}/${chart.chartName}`,
73
121
  releaseName,
74
122
  namespace,
75
- hasValuesFile: !!valuesPath,
123
+ hasValuesFile: !!valuesYaml,
76
124
  timeout,
77
125
  requestId
78
126
  });
79
- const result = await (0, helm_utils_1.deployHelmRelease)(chart, releaseName, namespace, valuesPath, timeout);
127
+ // PRD #343: All Helm operations go through plugin system
128
+ // First, add/update the Helm repository
129
+ const repoResult = await pluginManager.invokeTool('helm_repo_add', {
130
+ name: chart.repositoryName,
131
+ url: chart.repository
132
+ });
133
+ if (!repoResult.success) {
134
+ logger.warn('Helm repo add failed', { error: repoResult.error?.message });
135
+ }
136
+ // Deploy using helm_install with wait
137
+ const installResult = await pluginManager.invokeTool('helm_install', {
138
+ releaseName,
139
+ chart: `${chart.repositoryName}/${chart.chartName}`,
140
+ namespace,
141
+ values: valuesYaml,
142
+ version: chart.version,
143
+ dryRun: false,
144
+ wait: true,
145
+ timeout: `${timeout}s`,
146
+ createNamespace: true
147
+ });
148
+ // Check for nested error in result
149
+ let nestedError;
150
+ if (installResult.success && typeof installResult.result === 'object' && installResult.result !== null) {
151
+ const nestedResult = installResult.result;
152
+ if (nestedResult.success === false) {
153
+ nestedError = nestedResult.error || nestedResult.message || 'Helm install failed';
154
+ }
155
+ }
156
+ // Extract only the data field - never pass JSON wrapper
157
+ let output = '';
158
+ if (installResult.success && !nestedError) {
159
+ if (typeof installResult.result === 'object' && installResult.result !== null) {
160
+ const resultData = installResult.result;
161
+ if (resultData.data !== undefined) {
162
+ output = String(resultData.data);
163
+ }
164
+ else if (typeof resultData === 'string') {
165
+ output = resultData;
166
+ }
167
+ // Don't throw error here - empty output is acceptable for Helm
168
+ }
169
+ else {
170
+ output = String(installResult.result || '');
171
+ }
172
+ }
173
+ const result = {
174
+ success: installResult.success && !nestedError,
175
+ output,
176
+ error: nestedError || (!installResult.success ? installResult.error?.message : undefined)
177
+ };
80
178
  logger.info('Helm deployment completed', {
81
179
  success: result.success,
82
180
  solutionId: args.solutionId,
@@ -118,10 +216,11 @@ async function handleDeployManifestsTool(args, dotAI, logger, requestId) {
118
216
  };
119
217
  }
120
218
  // Capability-based solution: Use existing DeployOperation
219
+ // PRD #343: Pass pluginManager for kubectl operations
121
220
  logger.info('Using capability-based deployment flow', {
122
221
  solutionId: args.solutionId
123
222
  });
124
- const deployOp = new deploy_operation_1.DeployOperation();
223
+ const deployOp = new deploy_operation_1.DeployOperation(pluginManager);
125
224
  const deployOptions = {
126
225
  solutionId: args.solutionId,
127
226
  timeout
@@ -5,6 +5,7 @@
5
5
  import { z } from 'zod';
6
6
  import { DotAI } from '../core/index';
7
7
  import { Logger } from '../core/error-handling';
8
+ import type { PluginManager } from '../core/plugin-manager';
8
9
  export declare const GENERATEMANIFESTS_TOOL_NAME = "generateManifests";
9
10
  export declare const GENERATEMANIFESTS_TOOL_DESCRIPTION = "Generate final Kubernetes manifests from fully configured solution (ONLY after completing ALL stages: required, basic, advanced, and open)";
10
11
  export declare const GENERATEMANIFESTS_TOOL_INPUT_SCHEMA: {
@@ -13,11 +14,12 @@ export declare const GENERATEMANIFESTS_TOOL_INPUT_SCHEMA: {
13
14
  };
14
15
  /**
15
16
  * Direct MCP tool handler for generateManifests functionality
17
+ * PRD #343: pluginManager required for kubectl operations
16
18
  */
17
19
  export declare function handleGenerateManifestsTool(args: {
18
20
  solutionId: string;
19
21
  interaction_id?: string;
20
- }, dotAI: DotAI, logger: Logger, requestId: string): Promise<{
22
+ }, dotAI: DotAI, logger: Logger, requestId: string, pluginManager: PluginManager): Promise<{
21
23
  content: {
22
24
  type: 'text';
23
25
  text: string;
@@ -1 +1 @@
1
- {"version":3,"file":"generate-manifests.d.ts","sourceRoot":"","sources":["../../src/tools/generate-manifests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,KAAK,EAA0B,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA0BhD,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAC/D,eAAO,MAAM,kCAAkC,+IAA+I,CAAC;AAG/L,eAAO,MAAM,mCAAmC;;;CAG/C,CAAC;AAkvBF;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,EACrD,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAiUxD"}
1
+ {"version":3,"file":"generate-manifests.d.ts","sourceRoot":"","sources":["../../src/tools/generate-manifests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,KAAK,EAA0B,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAehD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAsD5D,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAC/D,eAAO,MAAM,kCAAkC,+IAA+I,CAAC;AAG/L,eAAO,MAAM,mCAAmC;;;CAG/C,CAAC;AA8xBF;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,EACrD,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAiUxD"}
@@ -44,7 +44,6 @@ const child_process_1 = require("child_process");
44
44
  const util_1 = require("util");
45
45
  const error_handling_1 = require("../core/error-handling");
46
46
  const index_1 = require("../core/index");
47
- const cluster_utils_1 = require("../core/cluster-utils");
48
47
  const schema_1 = require("../core/schema");
49
48
  const fs = __importStar(require("fs"));
50
49
  const path = __importStar(require("path"));
@@ -55,9 +54,45 @@ const solution_utils_1 = require("../core/solution-utils");
55
54
  const platform_utils_1 = require("../core/platform-utils");
56
55
  const crd_availability_1 = require("../core/crd-availability");
57
56
  const solution_cr_1 = require("../core/solution-cr");
58
- const helm_utils_1 = require("../core/helm-utils");
59
57
  const packaging_1 = require("../core/packaging");
60
58
  const visualization_1 = require("../core/visualization");
59
+ // PRD #343: Inline utilities (helm-utils.ts removed - all helm operations via plugin)
60
+ /**
61
+ * Ensure tmp directory exists
62
+ */
63
+ function ensureTmpDir() {
64
+ const tmpDir = path.join(process.cwd(), 'tmp');
65
+ if (!fs.existsSync(tmpDir)) {
66
+ fs.mkdirSync(tmpDir, { recursive: true });
67
+ }
68
+ return tmpDir;
69
+ }
70
+ /**
71
+ * Get the path for Helm values file
72
+ */
73
+ function getHelmValuesPath(solutionId) {
74
+ const tmpDir = path.join(process.cwd(), 'tmp');
75
+ return path.join(tmpDir, `${solutionId}-values.yaml`);
76
+ }
77
+ /**
78
+ * Build Helm command string for display to users
79
+ */
80
+ function buildHelmCommandForDisplay(chart, releaseName, namespace, valuesPath) {
81
+ const parts = [
82
+ 'helm upgrade --install',
83
+ releaseName,
84
+ `${chart.repositoryName}/${chart.chartName}`,
85
+ `--namespace ${namespace}`,
86
+ '--create-namespace'
87
+ ];
88
+ if (chart.version) {
89
+ parts.push(`--version ${chart.version}`);
90
+ }
91
+ if (valuesPath) {
92
+ parts.push(`-f ${valuesPath}`);
93
+ }
94
+ return parts.join(' ');
95
+ }
61
96
  const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
62
97
  // Tool metadata for direct MCP registration
63
98
  exports.GENERATEMANIFESTS_TOOL_NAME = 'generateManifests';
@@ -182,8 +217,9 @@ async function helmLint(chartDir, logger) {
182
217
  }
183
218
  /**
184
219
  * Validate manifests using multi-layer approach
220
+ * PRD #343: pluginManager required for kubectl operations
185
221
  */
186
- async function validateManifests(yamlPath) {
222
+ async function validateManifests(yamlPath, pluginManager) {
187
223
  // First check if file exists
188
224
  if (!fs.existsSync(yamlPath)) {
189
225
  return {
@@ -204,7 +240,8 @@ async function validateManifests(yamlPath) {
204
240
  };
205
241
  }
206
242
  // 2. kubectl dry-run validation using ManifestValidator
207
- const validator = new schema_1.ManifestValidator();
243
+ // PRD #343: Pass pluginManager for kubectl operations
244
+ const validator = new schema_1.ManifestValidator(pluginManager);
208
245
  return await validator.validateManifest(yamlPath, { dryRunMode: 'server' });
209
246
  }
210
247
  /**
@@ -311,34 +348,69 @@ ${errorContext.previousValues}
311
348
  return valuesContent;
312
349
  }
313
350
  /**
314
- * Validate Helm installation using dry-run (wrapper around shared utility)
351
+ * Validate Helm installation using dry-run via plugin
352
+ * PRD #343: All Helm operations go through plugin system
315
353
  */
316
- async function validateHelmInstallation(chart, releaseName, namespace, valuesPath, logger) {
317
- logger.info('Running Helm dry-run validation', {
354
+ async function validateHelmInstallation(chart, releaseName, namespace, valuesYaml, logger, pluginManager) {
355
+ logger.info('Running Helm dry-run validation via plugin', {
318
356
  chart: `${chart.repositoryName}/${chart.chartName}`,
319
357
  releaseName,
320
358
  namespace
321
359
  });
322
- const result = await (0, helm_utils_1.validateHelmDryRun)(chart, releaseName, namespace, valuesPath);
323
- if (result.success) {
324
- logger.info('Helm dry-run validation successful');
360
+ try {
361
+ // First, add/update the Helm repository
362
+ const repoResult = await pluginManager.invokeTool('helm_repo_add', {
363
+ name: chart.repositoryName,
364
+ url: chart.repository
365
+ });
366
+ if (!repoResult.success) {
367
+ logger.warn('Helm repo add failed', { error: repoResult.error?.message });
368
+ return {
369
+ valid: false,
370
+ errors: [repoResult.error?.message || 'Failed to add Helm repository'],
371
+ warnings: []
372
+ };
373
+ }
374
+ // Run helm install with dry-run
375
+ const installResult = await pluginManager.invokeTool('helm_install', {
376
+ releaseName,
377
+ chart: `${chart.repositoryName}/${chart.chartName}`,
378
+ namespace,
379
+ values: valuesYaml,
380
+ version: chart.version,
381
+ dryRun: true,
382
+ createNamespace: true
383
+ });
384
+ if (installResult.success) {
385
+ logger.info('Helm dry-run validation successful');
386
+ return {
387
+ valid: true,
388
+ errors: [],
389
+ warnings: []
390
+ };
391
+ }
392
+ logger.warn('Helm dry-run validation failed', { error: installResult.error?.message });
325
393
  return {
326
- valid: true,
327
- errors: [],
394
+ valid: false,
395
+ errors: [installResult.error?.message || 'Unknown Helm validation error'],
396
+ warnings: []
397
+ };
398
+ }
399
+ catch (error) {
400
+ const errorMessage = error instanceof Error ? error.message : String(error);
401
+ logger.error('Helm validation error', error);
402
+ return {
403
+ valid: false,
404
+ errors: [errorMessage],
328
405
  warnings: []
329
406
  };
330
407
  }
331
- logger.warn('Helm dry-run validation failed', { error: result.error });
332
- return {
333
- valid: false,
334
- errors: [result.error || 'Unknown Helm validation error'],
335
- warnings: []
336
- };
337
408
  }
338
409
  /**
339
410
  * Handle Helm solution generation
411
+ * PRD #343: pluginManager required for Helm operations
340
412
  */
341
- async function handleHelmGeneration(solution, solutionId, dotAI, logger, requestId, sessionManager, interaction_id) {
413
+ async function handleHelmGeneration(solution, solutionId, dotAI, logger, requestId, sessionManager, pluginManager, interaction_id) {
342
414
  const maxAttempts = 10;
343
415
  const chart = solution.chart;
344
416
  const userAnswers = (0, solution_utils_1.extractUserAnswers)(solution);
@@ -354,8 +426,8 @@ async function handleHelmGeneration(solution, solutionId, dotAI, logger, request
354
426
  });
355
427
  }
356
428
  // Prepare file paths using shared utilities
357
- (0, helm_utils_1.ensureTmpDir)();
358
- const valuesPath = (0, helm_utils_1.getHelmValuesPath)(solutionId);
429
+ ensureTmpDir();
430
+ const valuesPath = getHelmValuesPath(solutionId);
359
431
  // AI generation and validation loop
360
432
  let lastError;
361
433
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
@@ -375,8 +447,9 @@ async function handleHelmGeneration(solution, solutionId, dotAI, logger, request
375
447
  // Save attempt for debugging
376
448
  const attemptPath = valuesPath.replace('.yaml', `_attempt_${attempt.toString().padStart(2, '0')}.yaml`);
377
449
  fs.writeFileSync(attemptPath, valuesYaml, 'utf8');
378
- // Validate with helm dry-run
379
- const validation = await validateHelmInstallation(chart, releaseName, namespace, valuesPath, logger);
450
+ // Validate with helm dry-run via plugin
451
+ // PRD #343: Pass values content directly to plugin (no file path needed)
452
+ const validation = await validateHelmInstallation(chart, releaseName, namespace, valuesYaml, logger, pluginManager);
380
453
  if (validation.valid) {
381
454
  logger.info('Helm validation successful', {
382
455
  attempt,
@@ -385,7 +458,7 @@ async function handleHelmGeneration(solution, solutionId, dotAI, logger, request
385
458
  });
386
459
  // Build user-friendly helm command with generic values file path
387
460
  // (internal valuesPath is used for actual execution, not shown to user)
388
- const helmCommand = (0, helm_utils_1.buildHelmCommand)(chart, releaseName, namespace, 'values.yaml');
461
+ const helmCommand = buildHelmCommandForDisplay(chart, releaseName, namespace, 'values.yaml');
389
462
  // PRD #320: Update session with generateManifests data for visualization
390
463
  sessionManager.updateSession(solutionId, {
391
464
  ...solution,
@@ -528,8 +601,9 @@ function writePackageFiles(files, baseDir) {
528
601
  }
529
602
  /**
530
603
  * Package manifests and validate the output
604
+ * PRD #343: pluginManager required for kubectl operations
531
605
  */
532
- async function packageAndValidate(rawManifests, solution, outputFormat, outputPath, solutionId, dotAI, logger, interaction_id) {
606
+ async function packageAndValidate(rawManifests, solution, outputFormat, outputPath, solutionId, dotAI, logger, pluginManager, interaction_id) {
533
607
  const maxAttempts = 5;
534
608
  let packagingError;
535
609
  const tmpDir = path.join(process.cwd(), 'tmp');
@@ -597,7 +671,7 @@ async function packageAndValidate(rawManifests, solution, outputFormat, outputPa
597
671
  throw new Error('Render succeeded but no YAML content returned');
598
672
  }
599
673
  fs.writeFileSync(renderedYamlPath, renderResult.yaml, 'utf8');
600
- const validation = await validateManifests(renderedYamlPath);
674
+ const validation = await validateManifests(renderedYamlPath, pluginManager);
601
675
  if (validation.valid) {
602
676
  logger.info('Package validation successful', { format: outputFormat, attempt });
603
677
  cleanupPackageDir();
@@ -628,8 +702,9 @@ async function packageAndValidate(rawManifests, solution, outputFormat, outputPa
628
702
  }
629
703
  /**
630
704
  * Direct MCP tool handler for generateManifests functionality
705
+ * PRD #343: pluginManager required for kubectl operations
631
706
  */
632
- async function handleGenerateManifestsTool(args, dotAI, logger, requestId) {
707
+ async function handleGenerateManifestsTool(args, dotAI, logger, requestId, pluginManager) {
633
708
  return await error_handling_1.ErrorHandler.withErrorHandling(async () => {
634
709
  const maxAttempts = 10;
635
710
  logger.debug('Handling generateManifests request', {
@@ -641,8 +716,6 @@ async function handleGenerateManifestsTool(args, dotAI, logger, requestId) {
641
716
  // Initialize session manager
642
717
  const sessionManager = new generic_session_manager_1.GenericSessionManager('sol');
643
718
  logger.debug('Session manager initialized', { requestId });
644
- // Ensure cluster connectivity before proceeding
645
- await (0, cluster_utils_1.ensureClusterConnection)(dotAI, logger, requestId, 'GenerateManifestsTool');
646
719
  // Load solution session
647
720
  const session = sessionManager.getSession(args.solutionId);
648
721
  if (!session) {
@@ -672,7 +745,7 @@ async function handleGenerateManifestsTool(args, dotAI, logger, requestId) {
672
745
  solutionId: args.solutionId,
673
746
  chart: solution.chart ? `${solution.chart.repositoryName}/${solution.chart.chartName}` : 'unknown'
674
747
  });
675
- return await handleHelmGeneration(solution, args.solutionId, dotAI, logger, requestId, sessionManager, args.interaction_id);
748
+ return await handleHelmGeneration(solution, args.solutionId, dotAI, logger, requestId, sessionManager, pluginManager, args.interaction_id);
676
749
  }
677
750
  // Capability-based solution: Generate Kubernetes manifests
678
751
  logger.info('Using capability-based manifest generation flow', {
@@ -702,7 +775,7 @@ async function handleGenerateManifestsTool(args, dotAI, logger, requestId) {
702
775
  // Check if Solution CRD is available and generate Solution CR if present
703
776
  let solutionCR = '';
704
777
  try {
705
- const crdAvailable = await (0, crd_availability_1.isSolutionCRDAvailable)();
778
+ const crdAvailable = await (0, crd_availability_1.isSolutionCRDAvailable)(pluginManager);
706
779
  if (crdAvailable) {
707
780
  solutionCR = (0, solution_cr_1.generateSolutionCR)({
708
781
  solutionId: args.solutionId,
@@ -742,7 +815,8 @@ async function handleGenerateManifestsTool(args, dotAI, logger, requestId) {
742
815
  requestId
743
816
  });
744
817
  // Validate manifests
745
- const validation = await validateManifests(yamlPath);
818
+ // PRD #343: Pass pluginManager for kubectl operations
819
+ const validation = await validateManifests(yamlPath, pluginManager);
746
820
  if (validation.valid) {
747
821
  logger.info('Manifest validation successful', {
748
822
  attempt,
@@ -754,7 +828,7 @@ async function handleGenerateManifestsTool(args, dotAI, logger, requestId) {
754
828
  const outputPath = userAnswers.outputPath || './manifests';
755
829
  // Handle packaging based on outputFormat
756
830
  if (outputFormat === 'helm' || outputFormat === 'kustomize') {
757
- const packagingResult = await packageAndValidate(manifests, solution, outputFormat, outputPath, args.solutionId, dotAI, logger, args.interaction_id);
831
+ const packagingResult = await packageAndValidate(manifests, solution, outputFormat, outputPath, args.solutionId, dotAI, logger, pluginManager, args.interaction_id);
758
832
  // PRD #320: Update session with generateManifests data for visualization
759
833
  sessionManager.updateSession(args.solutionId, {
760
834
  ...solution,
@@ -1,15 +1,19 @@
1
1
  import { GenericSessionManager } from '../core/generic-session-manager';
2
+ import { PluginManager } from '../core/plugin-manager';
2
3
  import { Logger } from '../core/error-handling';
3
4
  import { OperateSessionData } from './operate';
4
5
  /**
5
6
  * Analyzes user intent and generates operational proposal using AI tool loop
6
7
  *
8
+ * PRD #343: pluginManager is required - all kubectl operations go through plugin.
9
+ *
7
10
  * @param intent - User's operational intent (e.g., "update my-api to v2.0")
8
11
  * @param logger - Logger instance
9
12
  * @param sessionManager - Session manager instance
13
+ * @param pluginManager - Plugin manager for kubectl operations
10
14
  * @param sessionId - Optional session ID for refinement
11
15
  * @param interaction_id - Optional interaction ID for eval datasets
12
16
  * @returns Operation output with proposed changes
13
17
  */
14
- export declare function analyzeIntent(intent: string, logger: Logger, sessionManager: GenericSessionManager<OperateSessionData>, sessionId?: string, interaction_id?: string): Promise<any>;
18
+ export declare function analyzeIntent(intent: string, logger: Logger, sessionManager: GenericSessionManager<OperateSessionData>, pluginManager: PluginManager, sessionId?: string, interaction_id?: string): Promise<any>;
15
19
  //# sourceMappingURL=operate-analysis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"operate-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/operate-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAGxE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhD,OAAO,EAEL,kBAAkB,EAMnB,MAAM,WAAW,CAAC;AAEnB;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,EACzD,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,GAAG,CAAC,CAoDd"}
1
+ {"version":3,"file":"operate-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/operate-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhD,OAAO,EAEL,kBAAkB,EAMnB,MAAM,WAAW,CAAC;AAEnB;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,EACzD,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,GAAG,CAAC,CAoDd"}
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.analyzeIntent = analyzeIntent;
4
- const kubectl_tools_1 = require("../core/kubectl-tools");
5
4
  const ai_provider_factory_1 = require("../core/ai-provider-factory");
6
5
  const shared_prompt_loader_1 = require("../core/shared-prompt-loader");
7
6
  const visualization_1 = require("../core/visualization");
@@ -9,22 +8,25 @@ const operate_1 = require("./operate");
9
8
  /**
10
9
  * Analyzes user intent and generates operational proposal using AI tool loop
11
10
  *
11
+ * PRD #343: pluginManager is required - all kubectl operations go through plugin.
12
+ *
12
13
  * @param intent - User's operational intent (e.g., "update my-api to v2.0")
13
14
  * @param logger - Logger instance
14
15
  * @param sessionManager - Session manager instance
16
+ * @param pluginManager - Plugin manager for kubectl operations
15
17
  * @param sessionId - Optional session ID for refinement
16
18
  * @param interaction_id - Optional interaction ID for eval datasets
17
19
  * @returns Operation output with proposed changes
18
20
  */
19
- async function analyzeIntent(intent, logger, sessionManager, sessionId, interaction_id) {
21
+ async function analyzeIntent(intent, logger, sessionManager, pluginManager, sessionId, interaction_id) {
20
22
  logger.info('Starting operate analysis', { intent, sessionId });
21
23
  // 1. Embed context (patterns, policies, capabilities)
22
24
  const context = await (0, operate_1.embedContext)(intent, logger);
23
25
  // 2. Load prompts (static system + dynamic user message)
24
26
  const systemPrompt = loadSystemPrompt();
25
27
  const userMessage = buildUserMessage(intent, context);
26
- // 3. Execute AI tool loop with kubectl tools
27
- const aiResult = await executeToolLoop(systemPrompt, userMessage, logger, interaction_id);
28
+ // 3. Execute AI tool loop with kubectl tools (PRD #343: via plugin)
29
+ const aiResult = await executeToolLoop(systemPrompt, userMessage, logger, pluginManager, interaction_id);
28
30
  // 4. Parse AI response into structured format
29
31
  const proposedChanges = parseAIResponse(aiResult, logger);
30
32
  // 5. Create and save session
@@ -77,25 +79,53 @@ function buildUserMessage(intent, context) {
77
79
  capabilities: capabilitiesText
78
80
  });
79
81
  }
82
+ /** Kubectl tool names for investigation and dry-run validation */
83
+ const KUBECTL_INVESTIGATION_TOOL_NAMES = [
84
+ 'kubectl_get',
85
+ 'kubectl_describe',
86
+ 'kubectl_logs',
87
+ 'kubectl_events',
88
+ 'kubectl_api_resources',
89
+ 'kubectl_get_crd_schema',
90
+ 'kubectl_get_resource_json',
91
+ // Dry-run tools for validation
92
+ 'kubectl_patch_dryrun',
93
+ 'kubectl_apply_dryrun',
94
+ 'kubectl_delete_dryrun'
95
+ ];
80
96
  /**
81
97
  * Executes AI tool loop with kubectl investigation tools
82
98
  * AI autonomously inspects cluster and validates changes with dry-run
83
99
  *
100
+ * PRD #343: Kubectl tools are routed through the plugin system.
101
+ *
84
102
  * @param systemPrompt - Static instructions (cacheable)
85
103
  * @param userMessage - Dynamic content with intent and context
86
104
  * @param logger - Logger instance
105
+ * @param pluginManager - Plugin manager for kubectl operations
87
106
  * @param interaction_id - Optional interaction ID for eval datasets
88
107
  * @returns AI's final response
89
108
  * @throws Error if AI fails to converge within 30 iterations
90
109
  */
91
- async function executeToolLoop(systemPrompt, userMessage, logger, interaction_id) {
110
+ async function executeToolLoop(systemPrompt, userMessage, logger, pluginManager, interaction_id) {
92
111
  logger.debug('Starting AI tool loop for operate analysis');
112
+ // PRD #343: Get kubectl tools from plugin
113
+ const kubectlTools = pluginManager.getDiscoveredTools().filter(t => KUBECTL_INVESTIGATION_TOOL_NAMES.includes(t.name));
114
+ if (kubectlTools.length === 0) {
115
+ throw new Error('No kubectl tools available from plugin. Ensure agentic-tools plugin is running.');
116
+ }
117
+ logger.debug('Using kubectl tools from plugin', {
118
+ toolCount: kubectlTools.length,
119
+ tools: kubectlTools.map(t => t.name)
120
+ });
121
+ // PRD #343: Create tool executor that routes through plugin
122
+ const toolExecutor = pluginManager.createToolExecutor();
93
123
  const aiProvider = (0, ai_provider_factory_1.createAIProvider)();
94
124
  const result = await aiProvider.toolLoop({
95
125
  systemPrompt,
96
126
  userMessage,
97
- tools: kubectl_tools_1.KUBECTL_INVESTIGATION_TOOLS,
98
- toolExecutor: kubectl_tools_1.executeKubectlTools,
127
+ tools: kubectlTools,
128
+ toolExecutor: toolExecutor,
99
129
  maxIterations: 30,
100
130
  operation: 'operate-analysis',
101
131
  evaluationContext: {
@@ -6,13 +6,15 @@
6
6
  */
7
7
  import { Logger } from '../core/error-handling';
8
8
  import { GenericSessionManager } from '../core/generic-session-manager';
9
+ import { PluginManager } from '../core/plugin-manager';
9
10
  import { OperateSessionData, OperateOutput } from './operate';
10
11
  /**
11
12
  * Executes approved operational changes
12
13
  * @param sessionId - Session ID with approved changes
13
14
  * @param logger - Logger instance
14
15
  * @param sessionManager - Session manager instance
16
+ * @param pluginManager - Plugin manager for kubectl operations (PRD #343)
15
17
  * @returns Operation output with execution results
16
18
  */
17
- export declare function executeOperations(sessionId: string, logger: Logger, sessionManager: GenericSessionManager<OperateSessionData>): Promise<OperateOutput>;
19
+ export declare function executeOperations(sessionId: string, logger: Logger, sessionManager: GenericSessionManager<OperateSessionData>, pluginManager: PluginManager): Promise<OperateOutput>;
18
20
  //# sourceMappingURL=operate-execution.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"operate-execution.d.ts","sourceRoot":"","sources":["../../src/tools/operate-execution.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAA8C,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAExE,OAAO,EAAE,kBAAkB,EAAmB,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/E;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,GACxD,OAAO,CAAC,aAAa,CAAC,CAwIxB"}
1
+ {"version":3,"file":"operate-execution.d.ts","sourceRoot":"","sources":["../../src/tools/operate-execution.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAA8C,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAmB,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/E;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,qBAAqB,CAAC,kBAAkB,CAAC,EACzD,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,aAAa,CAAC,CA0IxB"}
@@ -15,9 +15,10 @@ const remediate_1 = require("./remediate");
15
15
  * @param sessionId - Session ID with approved changes
16
16
  * @param logger - Logger instance
17
17
  * @param sessionManager - Session manager instance
18
+ * @param pluginManager - Plugin manager for kubectl operations (PRD #343)
18
19
  * @returns Operation output with execution results
19
20
  */
20
- async function executeOperations(sessionId, logger, sessionManager) {
21
+ async function executeOperations(sessionId, logger, sessionManager, pluginManager) {
21
22
  logger.info('Starting operation execution', { sessionId });
22
23
  try {
23
24
  // 1. Load session with approved commands
@@ -36,8 +37,8 @@ async function executeOperations(sessionId, logger, sessionManager) {
36
37
  commandCount: session.data.commands.length,
37
38
  intent: session.data.intent
38
39
  });
39
- // 2. Execute commands using shared executor
40
- const { results, overallSuccess } = await (0, command_executor_1.executeCommands)(session.data.commands, logger, {
40
+ // 2. Execute commands using shared executor (PRD #343: via plugin)
41
+ const { results, overallSuccess } = await (0, command_executor_1.executeCommands)(session.data.commands, logger, pluginManager, {
41
42
  sessionId,
42
43
  context: 'operation',
43
44
  logMetadata: { intent: session.data.intent }
@@ -59,11 +60,12 @@ async function executeOperations(sessionId, logger, sessionManager) {
59
60
  });
60
61
  try {
61
62
  // Call remediate tool internally with validation intent
63
+ // PRD #343: Pass pluginManager for kubectl operations
62
64
  const validationResponse = await (0, remediate_1.handleRemediateTool)({
63
65
  issue: session.data.validationIntent,
64
66
  executedCommands: session.data.commands,
65
67
  interaction_id: session.data.interaction_id
66
- });
68
+ }, pluginManager);
67
69
  // Extract validation result from remediate response
68
70
  const validationData = JSON.parse(validationResponse.content[0].text);
69
71
  if (validationData.status === 'resolved' || validationData.status === 'no_issue_found') {