vcluster-yaml-mcp-server 1.3.2 → 1.4.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 (52) hide show
  1. package/dist/cli-handlers.d.ts +22 -0
  2. package/dist/cli-handlers.js +258 -0
  3. package/dist/cli-utils.d.ts +18 -0
  4. package/dist/cli-utils.js +52 -0
  5. package/dist/cli.d.ts +8 -0
  6. package/dist/cli.js +201 -0
  7. package/dist/completions.d.ts +17 -0
  8. package/{src → dist}/completions.js +10 -18
  9. package/dist/formatters.d.ts +54 -0
  10. package/dist/formatters.js +151 -0
  11. package/dist/github.d.ts +15 -0
  12. package/dist/github.js +195 -0
  13. package/dist/http-server.d.ts +3 -0
  14. package/dist/http-server.js +158 -0
  15. package/dist/index.d.ts +3 -0
  16. package/{src → dist}/index.js +2 -4
  17. package/dist/instrumentation.d.ts +2 -0
  18. package/{src → dist}/instrumentation.js +16 -21
  19. package/dist/middleware/auth.d.ts +7 -0
  20. package/dist/middleware/auth.js +38 -0
  21. package/dist/schema-validator.d.ts +71 -0
  22. package/dist/schema-validator.js +329 -0
  23. package/dist/server-info.d.ts +38 -0
  24. package/dist/server-info.js +137 -0
  25. package/dist/server.d.ts +3 -0
  26. package/dist/server.js +125 -0
  27. package/dist/snippet-validator.d.ts +35 -0
  28. package/dist/snippet-validator.js +330 -0
  29. package/dist/tool-handlers.d.ts +102 -0
  30. package/dist/tool-handlers.js +349 -0
  31. package/dist/tool-registry.d.ts +20 -0
  32. package/dist/tool-registry.js +35 -0
  33. package/dist/types/index.d.ts +168 -0
  34. package/dist/types/index.js +5 -0
  35. package/dist/validation-rules.d.ts +10 -0
  36. package/dist/validation-rules.js +158 -0
  37. package/package.json +28 -14
  38. package/src/cli-handlers.js +0 -290
  39. package/src/cli-utils.js +0 -62
  40. package/src/cli.js +0 -219
  41. package/src/formatters.js +0 -168
  42. package/src/github.js +0 -220
  43. package/src/http-server.js +0 -178
  44. package/src/middleware/auth.js +0 -42
  45. package/src/schema-validator.js +0 -380
  46. package/src/server-info.js +0 -153
  47. package/src/server.js +0 -180
  48. package/src/snippet-validator.js +0 -382
  49. package/src/snippet-validator.test.js +0 -366
  50. package/src/tool-handlers.js +0 -408
  51. package/src/tool-registry.js +0 -45
  52. package/src/validation-rules.js +0 -181
@@ -0,0 +1,22 @@
1
+ /**
2
+ * CLI handlers that bridge CLI commands to underlying logic
3
+ * Reuses githubClient and validation logic from server.js
4
+ * Returns structured data for CLI formatters
5
+ */
6
+ import type { CliQueryOptions, CliValidateOptions, CliResult } from './types/index.js';
7
+ /**
8
+ * Handle query command
9
+ * Searches for configuration fields in vCluster YAML
10
+ */
11
+ export declare function handleQuery(query: string, options: CliQueryOptions): Promise<CliResult>;
12
+ /**
13
+ * Handle list-versions command
14
+ * Lists available vCluster versions from GitHub
15
+ */
16
+ export declare function handleListVersions(): Promise<CliResult>;
17
+ /**
18
+ * Handle validate command
19
+ * Validates vCluster YAML configuration
20
+ */
21
+ export declare function handleValidate(content: string, options: CliValidateOptions): Promise<CliResult>;
22
+ //# sourceMappingURL=cli-handlers.d.ts.map
@@ -0,0 +1,258 @@
1
+ /**
2
+ * CLI handlers that bridge CLI commands to underlying logic
3
+ * Reuses githubClient and validation logic from server.js
4
+ * Returns structured data for CLI formatters
5
+ */
6
+ import yaml from 'js-yaml';
7
+ import { githubClient } from './github.js';
8
+ import { validateSnippet } from './snippet-validator.js';
9
+ // Helper function to get the type of a value
10
+ function getType(value) {
11
+ if (value === null)
12
+ return 'null';
13
+ if (Array.isArray(value))
14
+ return 'array';
15
+ if (typeof value === 'object')
16
+ return 'object';
17
+ if (typeof value === 'number') {
18
+ return Number.isInteger(value) ? 'integer' : 'number';
19
+ }
20
+ return typeof value;
21
+ }
22
+ // Helper function to rank search results
23
+ function rankResult(item, searchTerm) {
24
+ const pathLower = item.path.toLowerCase();
25
+ const keyLower = item.key.toLowerCase();
26
+ let score = 0;
27
+ // Exact match
28
+ if (pathLower === searchTerm || keyLower === searchTerm) {
29
+ score += 100;
30
+ }
31
+ // Starts with search term
32
+ if (pathLower.startsWith(searchTerm) || keyLower.startsWith(searchTerm)) {
33
+ score += 50;
34
+ }
35
+ // Ends with search term
36
+ if (pathLower.endsWith(searchTerm) || keyLower.endsWith(searchTerm)) {
37
+ score += 40;
38
+ }
39
+ // Contains search term
40
+ if (pathLower.includes(searchTerm) || keyLower.includes(searchTerm)) {
41
+ score += 30;
42
+ }
43
+ // Prefer leaf nodes (actual values)
44
+ if (item.isLeaf) {
45
+ score += 10;
46
+ }
47
+ // Prefer shorter paths (more specific)
48
+ const pathDepth = item.path.split('.').length;
49
+ score -= pathDepth;
50
+ return score;
51
+ }
52
+ /**
53
+ * Handle query command
54
+ * Searches for configuration fields in vCluster YAML
55
+ */
56
+ export async function handleQuery(query, options) {
57
+ const version = options.version || 'main';
58
+ const fileName = options.file || 'chart/values.yaml';
59
+ let yamlData;
60
+ try {
61
+ yamlData = await githubClient.getYamlContent(fileName, version);
62
+ }
63
+ catch (error) {
64
+ return {
65
+ success: false,
66
+ error: `Could not load ${fileName} from GitHub (version: ${version}). Error: ${error instanceof Error ? error.message : String(error)}`,
67
+ metadata: {
68
+ query,
69
+ file: fileName,
70
+ version
71
+ }
72
+ };
73
+ }
74
+ const searchTerm = query.toLowerCase();
75
+ const results = [];
76
+ // Helper function to extract all paths and values
77
+ function extractInfo(obj, path = '') {
78
+ const info = [];
79
+ if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
80
+ for (const [key, value] of Object.entries(obj)) {
81
+ const currentPath = path ? `${path}.${key}` : key;
82
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
83
+ info.push({ path: currentPath, key, value, isLeaf: false });
84
+ info.push(...extractInfo(value, currentPath));
85
+ }
86
+ else {
87
+ info.push({ path: currentPath, key, value, isLeaf: true });
88
+ }
89
+ }
90
+ }
91
+ return info;
92
+ }
93
+ const allInfo = extractInfo(yamlData);
94
+ // Support dot notation queries
95
+ const isDotNotation = searchTerm.includes('.');
96
+ if (isDotNotation) {
97
+ // Exact and partial dot notation matching
98
+ for (const item of allInfo) {
99
+ const pathLower = item.path.toLowerCase();
100
+ if (pathLower === searchTerm ||
101
+ pathLower.endsWith(searchTerm) ||
102
+ pathLower.includes(searchTerm)) {
103
+ results.push(item);
104
+ }
105
+ }
106
+ }
107
+ else {
108
+ // Keyword-based search
109
+ const keywords = searchTerm.split(/\s+/);
110
+ for (const item of allInfo) {
111
+ const pathLower = item.path.toLowerCase();
112
+ const keyLower = item.key.toLowerCase();
113
+ const valueStr = JSON.stringify(item.value).toLowerCase();
114
+ const allKeywordsMatch = keywords.every(kw => pathLower.includes(kw) || keyLower.includes(kw) || valueStr.includes(kw));
115
+ if (allKeywordsMatch) {
116
+ results.push(item);
117
+ }
118
+ }
119
+ }
120
+ // Sort results by relevance
121
+ results.sort((a, b) => {
122
+ const scoreA = rankResult(a, searchTerm);
123
+ const scoreB = rankResult(b, searchTerm);
124
+ return scoreB - scoreA;
125
+ });
126
+ // Format results for CLI output
127
+ const formattedResults = results.slice(0, 50).map(item => ({
128
+ field: item.path,
129
+ value: item.value,
130
+ type: getType(item.value),
131
+ path: item.path,
132
+ description: '' // Could be enhanced with comments parsing
133
+ }));
134
+ return {
135
+ success: true,
136
+ results: formattedResults,
137
+ metadata: {
138
+ query,
139
+ file: fileName,
140
+ version,
141
+ resultCount: formattedResults.length,
142
+ totalMatches: results.length
143
+ }
144
+ };
145
+ }
146
+ /**
147
+ * Handle list-versions command
148
+ * Lists available vCluster versions from GitHub
149
+ */
150
+ export async function handleListVersions() {
151
+ try {
152
+ const tags = await githubClient.getTags();
153
+ // Only show versions starting with 'v'
154
+ const versionTags = tags.filter(tag => tag.startsWith('v'));
155
+ // Always include main branch
156
+ const versions = ['main', ...versionTags];
157
+ return {
158
+ success: true,
159
+ versions,
160
+ metadata: {
161
+ totalCount: versions.length,
162
+ source: 'github'
163
+ }
164
+ };
165
+ }
166
+ catch (error) {
167
+ return {
168
+ success: false,
169
+ error: `Failed to fetch versions: ${error instanceof Error ? error.message : String(error)}`,
170
+ versions: [],
171
+ metadata: {
172
+ totalCount: 0,
173
+ source: 'github'
174
+ }
175
+ };
176
+ }
177
+ }
178
+ /**
179
+ * Handle validate command
180
+ * Validates vCluster YAML configuration
181
+ */
182
+ export async function handleValidate(content, options) {
183
+ const version = options.version || 'main';
184
+ // Validate YAML syntax first
185
+ try {
186
+ yaml.load(content);
187
+ }
188
+ catch (error) {
189
+ return {
190
+ success: false,
191
+ valid: false,
192
+ errors: [
193
+ {
194
+ path: 'root',
195
+ message: error instanceof Error ? error.message : String(error),
196
+ type: 'syntax'
197
+ }
198
+ ],
199
+ metadata: {
200
+ version,
201
+ contentLength: content.length
202
+ }
203
+ };
204
+ }
205
+ // Fetch schema for validation
206
+ try {
207
+ const schemaContent = await githubClient.getFileContent('chart/values.schema.json', version);
208
+ const fullSchema = JSON.parse(schemaContent);
209
+ // Use snippet validator
210
+ const result = validateSnippet(content, fullSchema, version);
211
+ if (result.valid) {
212
+ return {
213
+ success: true,
214
+ valid: true,
215
+ errors: [],
216
+ metadata: {
217
+ version,
218
+ contentLength: content.length
219
+ }
220
+ };
221
+ }
222
+ else {
223
+ // Format errors for CLI
224
+ const errors = (result.errors || []).map(err => ({
225
+ path: err.path || 'root',
226
+ message: err.message || 'Validation error',
227
+ type: err.keyword || 'validation'
228
+ }));
229
+ return {
230
+ success: true,
231
+ valid: false,
232
+ errors,
233
+ metadata: {
234
+ version,
235
+ contentLength: content.length
236
+ }
237
+ };
238
+ }
239
+ }
240
+ catch (error) {
241
+ return {
242
+ success: false,
243
+ valid: false,
244
+ errors: [
245
+ {
246
+ path: 'root',
247
+ message: `Failed to load schema: ${error instanceof Error ? error.message : String(error)}`,
248
+ type: 'schema-error'
249
+ }
250
+ ],
251
+ metadata: {
252
+ version,
253
+ contentLength: content.length
254
+ }
255
+ };
256
+ }
257
+ }
258
+ //# sourceMappingURL=cli-handlers.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * CLI utility functions
3
+ * Provides helpers for stdin reading and file operations
4
+ */
5
+ export interface ContentSource {
6
+ content: string;
7
+ source: string;
8
+ }
9
+ /**
10
+ * Read content from stdin
11
+ * Used for piping content to CLI commands
12
+ */
13
+ export declare function readStdin(): Promise<string>;
14
+ /**
15
+ * Read content from a file or stdin based on the file argument
16
+ */
17
+ export declare function readContentSource(file?: string): Promise<ContentSource>;
18
+ //# sourceMappingURL=cli-utils.d.ts.map
@@ -0,0 +1,52 @@
1
+ /**
2
+ * CLI utility functions
3
+ * Provides helpers for stdin reading and file operations
4
+ */
5
+ import { readFile } from 'fs/promises';
6
+ import { stdin } from 'process';
7
+ /**
8
+ * Read content from stdin
9
+ * Used for piping content to CLI commands
10
+ */
11
+ export async function readStdin() {
12
+ return new Promise((resolve, reject) => {
13
+ let data = '';
14
+ stdin.setEncoding('utf8');
15
+ stdin.on('data', (chunk) => data += chunk);
16
+ stdin.on('end', () => resolve(data));
17
+ stdin.on('error', reject);
18
+ });
19
+ }
20
+ /**
21
+ * Read content from a file or stdin based on the file argument
22
+ */
23
+ export async function readContentSource(file) {
24
+ // Read from stdin if no file provided or file is '-'
25
+ if (!file || file === '-') {
26
+ // If no file argument provided (not even '-'), check if we're in interactive mode
27
+ // In interactive mode (TTY), we should not wait for stdin
28
+ if (!file) {
29
+ // stdin.isTTY is true when running in interactive terminal
30
+ // stdin.isTTY is false/undefined when piping or redirecting
31
+ const isInteractive = stdin.isTTY === true;
32
+ if (isInteractive) {
33
+ throw new Error('No input provided. Please specify a file or pipe content via stdin.\n' +
34
+ 'Examples:\n' +
35
+ ' vcluster-yaml validate my-config.yaml\n' +
36
+ ' cat my-config.yaml | vcluster-yaml validate -\n' +
37
+ ' vcluster-yaml validate --help');
38
+ }
39
+ }
40
+ const content = await readStdin();
41
+ return { content, source: 'stdin' };
42
+ }
43
+ // Read from file
44
+ try {
45
+ const content = await readFile(file, 'utf-8');
46
+ return { content, source: file };
47
+ }
48
+ catch (error) {
49
+ throw new Error(`Cannot read file '${file}': ${error instanceof Error ? error.message : String(error)}`);
50
+ }
51
+ }
52
+ //# sourceMappingURL=cli-utils.js.map
package/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * vCluster CLI - Standalone command-line interface
4
+ * Provides query, validate, and list-versions commands
5
+ * Wraps MCP server functionality with user-friendly CLI
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js ADDED
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * vCluster CLI - Standalone command-line interface
4
+ * Provides query, validate, and list-versions commands
5
+ * Wraps MCP server functionality with user-friendly CLI
6
+ */
7
+ import { Command } from 'commander';
8
+ import { readFile } from 'fs/promises';
9
+ import { fileURLToPath } from 'url';
10
+ import { dirname, join } from 'path';
11
+ import { handleQuery, handleListVersions, handleValidate } from './cli-handlers.js';
12
+ import { formatOutput } from './formatters.js';
13
+ import { readContentSource } from './cli-utils.js';
14
+ import { generateBashCompletion, generateZshCompletion, getInstallInstructions } from './completions.js';
15
+ // Get package.json version
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ const packageJson = JSON.parse(await readFile(join(__dirname, '../package.json'), 'utf-8'));
19
+ const program = new Command();
20
+ program
21
+ .name('vcluster-yaml')
22
+ .description('vCluster YAML configuration CLI')
23
+ .version(packageJson.version);
24
+ // Query command
25
+ program
26
+ .command('query <query>')
27
+ .description('Search for vCluster configuration fields')
28
+ .option('--file <file>', 'Configuration file to search', 'chart/values.yaml')
29
+ .option('-s, --schema-version <version>', 'vCluster version or branch', 'main')
30
+ .option('-f, --format <format>', 'Output format: json, yaml, table (default: table)', 'table')
31
+ .addHelpText('after', `
32
+ Examples:
33
+ $ vcluster-yaml query sync
34
+ $ vcluster-yaml query sync --schema-version v0.24.0
35
+ $ vcluster-yaml query "controlPlane.replicas"
36
+ `)
37
+ .action(async (query, options) => {
38
+ try {
39
+ const format = options.format;
40
+ // Validate format option
41
+ if (!['json', 'yaml', 'table'].includes(format)) {
42
+ console.error(`Error: Invalid format "${format}". Must be one of: json, yaml, table`);
43
+ process.exit(1);
44
+ }
45
+ // Add validation for empty query
46
+ if (!query || query.trim() === '') {
47
+ console.error(`Error: Query cannot be empty. Try 'vcluster-yaml query sync' or see examples with --help`);
48
+ process.exit(1);
49
+ }
50
+ const result = await handleQuery(query, {
51
+ file: options.file || 'chart/values.yaml',
52
+ version: options.schemaVersion || 'main'
53
+ });
54
+ if (!result.success) {
55
+ // Error case - output error message and exit with code 1
56
+ if (format === 'json') {
57
+ console.log(JSON.stringify(result, null, 2));
58
+ }
59
+ else {
60
+ console.error(result.error);
61
+ }
62
+ process.exit(1);
63
+ }
64
+ const output = formatOutput(result, format, 'query');
65
+ console.log(output);
66
+ process.exit(0);
67
+ }
68
+ catch (error) {
69
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
70
+ process.exit(1);
71
+ }
72
+ });
73
+ // List versions command
74
+ program
75
+ .command('list-versions')
76
+ .description('List available vCluster versions')
77
+ .option('-f, --format <format>', 'Output format: json, yaml, table (default: table)', 'table')
78
+ .action(async (options) => {
79
+ try {
80
+ const format = options.format;
81
+ // Validate format option
82
+ if (!['json', 'yaml', 'table'].includes(format)) {
83
+ console.error(`Error: Invalid format "${format}". Must be one of: json, yaml, table`);
84
+ process.exit(1);
85
+ }
86
+ const result = await handleListVersions();
87
+ if (!result.success) {
88
+ if (format === 'json') {
89
+ console.log(JSON.stringify(result, null, 2));
90
+ }
91
+ else {
92
+ console.error(result.error);
93
+ }
94
+ process.exit(1);
95
+ }
96
+ const output = formatOutput(result, format, 'list-versions');
97
+ console.log(output);
98
+ process.exit(0);
99
+ }
100
+ catch (error) {
101
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
102
+ process.exit(1);
103
+ }
104
+ });
105
+ // Validate command
106
+ program
107
+ .command('validate [file]')
108
+ .description('Validate vCluster configuration')
109
+ .option('-s, --schema-version <version>', 'vCluster version for schema', 'main')
110
+ .option('-f, --format <format>', 'Output format: json, yaml, table (default: table)', 'table')
111
+ .addHelpText('after', `
112
+ Arguments:
113
+ file YAML file to validate (use '-' for stdin, omit to read from stdin)
114
+
115
+ Examples:
116
+ $ vcluster-yaml validate vcluster.yaml
117
+ $ vcluster-yaml validate vcluster.yaml --schema-version v0.24.0
118
+ $ cat vcluster.yaml | vcluster-yaml validate -
119
+ $ vcluster-yaml validate - < vcluster.yaml
120
+ `)
121
+ .action(async (file, options) => {
122
+ try {
123
+ const format = options.format;
124
+ // Validate format option
125
+ if (!['json', 'yaml', 'table'].includes(format)) {
126
+ console.error(`Error: Invalid format "${format}". Must be one of: json, yaml, table`);
127
+ process.exit(1);
128
+ }
129
+ // Read content from file or stdin
130
+ let content;
131
+ try {
132
+ const result = await readContentSource(file);
133
+ content = result.content;
134
+ }
135
+ catch (error) {
136
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
137
+ process.exit(1);
138
+ }
139
+ // Check for empty content
140
+ if (!content || content.trim() === '') {
141
+ console.error(`Error: No content to validate. Please provide a file path or pipe content via stdin.`);
142
+ process.exit(1);
143
+ }
144
+ const result = await handleValidate(content, {
145
+ version: options.schemaVersion || 'main'
146
+ });
147
+ // For validation, always output the result (even if not successful)
148
+ // The formatOutput will handle error cases appropriately
149
+ const output = formatOutput(result, format, 'validate');
150
+ console.log(output);
151
+ // Exit with code 1 if validation failed OR if we couldn't load schema
152
+ if (!result.success || !result.valid) {
153
+ process.exit(1);
154
+ }
155
+ process.exit(0);
156
+ }
157
+ catch (error) {
158
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
159
+ process.exit(1);
160
+ }
161
+ });
162
+ // Completion command
163
+ program
164
+ .command('completion <shell>')
165
+ .description('Generate shell completion script')
166
+ .addHelpText('after', `
167
+ Supported shells:
168
+ bash Bash completion script
169
+ zsh Zsh completion script
170
+
171
+ Examples:
172
+ $ vcluster-yaml completion bash > ~/.vcluster-yaml-completion.bash
173
+ $ vcluster-yaml completion zsh > ~/.zsh/completion/_vcluster-yaml
174
+ $ vcluster-yaml completion bash --help
175
+ `)
176
+ .action((shell) => {
177
+ const validShells = ['bash', 'zsh'];
178
+ if (!validShells.includes(shell)) {
179
+ console.error(`Error: Unsupported shell "${shell}". Supported shells: ${validShells.join(', ')}`);
180
+ console.error('');
181
+ console.error('Examples:');
182
+ console.error(' vcluster-yaml completion bash > ~/.vcluster-yaml-completion.bash');
183
+ console.error(' vcluster-yaml completion zsh > ~/.zsh/completion/_vcluster-yaml');
184
+ process.exit(1);
185
+ }
186
+ let script;
187
+ if (shell === 'bash') {
188
+ script = generateBashCompletion();
189
+ }
190
+ else {
191
+ script = generateZshCompletion();
192
+ }
193
+ // Output the script
194
+ console.log(script);
195
+ // Add installation instructions to stderr so they don't end up in the script
196
+ console.error('');
197
+ console.error(getInstallInstructions(shell));
198
+ });
199
+ // Parse arguments
200
+ program.parse();
201
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Shell completion generators
3
+ * Generates bash and zsh completion scripts for vcluster-yaml CLI
4
+ */
5
+ /**
6
+ * Generate bash completion script
7
+ */
8
+ export declare function generateBashCompletion(): string;
9
+ /**
10
+ * Generate zsh completion script
11
+ */
12
+ export declare function generateZshCompletion(): string;
13
+ /**
14
+ * Display installation instructions for a shell
15
+ */
16
+ export declare function getInstallInstructions(shell: string): string;
17
+ //# sourceMappingURL=completions.d.ts.map
@@ -2,13 +2,11 @@
2
2
  * Shell completion generators
3
3
  * Generates bash and zsh completion scripts for vcluster-yaml CLI
4
4
  */
5
-
6
5
  /**
7
6
  * Generate bash completion script
8
- * @returns {string} Bash completion script
9
7
  */
10
8
  export function generateBashCompletion() {
11
- return `# vcluster-yaml bash completion
9
+ return `# vcluster-yaml bash completion
12
10
 
13
11
  _vcluster_yaml_completions() {
14
12
  local cur prev words cword
@@ -82,13 +80,11 @@ _vcluster_yaml_completions() {
82
80
  complete -F _vcluster_yaml_completions vcluster-yaml
83
81
  `;
84
82
  }
85
-
86
83
  /**
87
84
  * Generate zsh completion script
88
- * @returns {string} Zsh completion script
89
85
  */
90
86
  export function generateZshCompletion() {
91
- return `#compdef vcluster-yaml
87
+ return `#compdef vcluster-yaml
92
88
 
93
89
  # vcluster-yaml zsh completion
94
90
 
@@ -183,15 +179,12 @@ _vcluster_yaml() {
183
179
  _vcluster_yaml "$@"
184
180
  `;
185
181
  }
186
-
187
182
  /**
188
183
  * Display installation instructions for a shell
189
- * @param {string} shell - Shell type (bash or zsh)
190
- * @returns {string} Installation instructions
191
184
  */
192
185
  export function getInstallInstructions(shell) {
193
- if (shell === 'bash') {
194
- return `
186
+ if (shell === 'bash') {
187
+ return `
195
188
  Bash Completion Installation:
196
189
 
197
190
  1. Save the completion script:
@@ -206,10 +199,9 @@ Bash Completion Installation:
206
199
  Or install system-wide (requires sudo):
207
200
  $ sudo vcluster-yaml completion bash > /etc/bash_completion.d/vcluster-yaml
208
201
  `;
209
- }
210
-
211
- if (shell === 'zsh') {
212
- return `
202
+ }
203
+ if (shell === 'zsh') {
204
+ return `
213
205
  Zsh Completion Installation:
214
206
 
215
207
  1. Create completion directory if needed:
@@ -228,7 +220,7 @@ Zsh Completion Installation:
228
220
  Or install system-wide (requires sudo):
229
221
  $ sudo vcluster-yaml completion zsh > /usr/local/share/zsh/site-functions/_vcluster-yaml
230
222
  `;
231
- }
232
-
233
- return 'Unsupported shell. Available: bash, zsh';
223
+ }
224
+ return 'Unsupported shell. Available: bash, zsh';
234
225
  }
226
+ //# sourceMappingURL=completions.js.map