@lenne.tech/cli 1.2.0 → 1.3.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 (36) hide show
  1. package/build/commands/claude/install-plugin.js +339 -0
  2. package/package.json +1 -1
  3. package/build/commands/claude/install-commands.js +0 -337
  4. package/build/commands/claude/install-mcps.js +0 -258
  5. package/build/commands/claude/install-skills.js +0 -693
  6. package/build/lib/mcp-registry.js +0 -80
  7. package/build/templates/claude-commands/code-cleanup.md +0 -82
  8. package/build/templates/claude-commands/commit-message.md +0 -21
  9. package/build/templates/claude-commands/create-story.md +0 -435
  10. package/build/templates/claude-commands/mr-description-clipboard.md +0 -48
  11. package/build/templates/claude-commands/mr-description.md +0 -33
  12. package/build/templates/claude-commands/sec-review.md +0 -62
  13. package/build/templates/claude-commands/skill-optimize.md +0 -481
  14. package/build/templates/claude-commands/test-generate.md +0 -45
  15. package/build/templates/claude-skills/building-stories-with-tdd/SKILL.md +0 -265
  16. package/build/templates/claude-skills/building-stories-with-tdd/code-quality.md +0 -276
  17. package/build/templates/claude-skills/building-stories-with-tdd/database-indexes.md +0 -182
  18. package/build/templates/claude-skills/building-stories-with-tdd/examples.md +0 -1383
  19. package/build/templates/claude-skills/building-stories-with-tdd/handling-existing-tests.md +0 -197
  20. package/build/templates/claude-skills/building-stories-with-tdd/reference.md +0 -1427
  21. package/build/templates/claude-skills/building-stories-with-tdd/security-review.md +0 -307
  22. package/build/templates/claude-skills/building-stories-with-tdd/workflow.md +0 -1004
  23. package/build/templates/claude-skills/generating-nest-servers/SKILL.md +0 -303
  24. package/build/templates/claude-skills/generating-nest-servers/configuration.md +0 -285
  25. package/build/templates/claude-skills/generating-nest-servers/declare-keyword-warning.md +0 -133
  26. package/build/templates/claude-skills/generating-nest-servers/description-management.md +0 -226
  27. package/build/templates/claude-skills/generating-nest-servers/examples.md +0 -893
  28. package/build/templates/claude-skills/generating-nest-servers/framework-guide.md +0 -259
  29. package/build/templates/claude-skills/generating-nest-servers/quality-review.md +0 -864
  30. package/build/templates/claude-skills/generating-nest-servers/reference.md +0 -487
  31. package/build/templates/claude-skills/generating-nest-servers/security-rules.md +0 -371
  32. package/build/templates/claude-skills/generating-nest-servers/verification-checklist.md +0 -262
  33. package/build/templates/claude-skills/generating-nest-servers/workflow-process.md +0 -1061
  34. package/build/templates/claude-skills/using-lt-cli/SKILL.md +0 -284
  35. package/build/templates/claude-skills/using-lt-cli/examples.md +0 -546
  36. package/build/templates/claude-skills/using-lt-cli/reference.md +0 -513
@@ -1,337 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const os_1 = require("os");
13
- const path_1 = require("path");
14
- /**
15
- * Get command description from .md frontmatter
16
- */
17
- function getCommandDescription(commandPath, filesystem) {
18
- if (!filesystem.exists(commandPath)) {
19
- return 'No description available';
20
- }
21
- const content = filesystem.read(commandPath);
22
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
23
- if (!frontmatterMatch) {
24
- return 'No description available';
25
- }
26
- const frontmatter = frontmatterMatch[1];
27
- const descMatch = frontmatter.match(/description:\s*([^\n]+)/);
28
- return descMatch ? descMatch[1].trim() : 'No description available';
29
- }
30
- /**
31
- * Compare semantic versions
32
- * Returns true if sourceVersion >= targetVersion
33
- */
34
- function isVersionNewer(sourceVersion, targetVersion) {
35
- const parseSemver = (version) => {
36
- return version.split('.').map(n => parseInt(n, 10) || 0);
37
- };
38
- const source = parseSemver(sourceVersion);
39
- const target = parseSemver(targetVersion);
40
- // Compare major, minor, patch
41
- for (let i = 0; i < 3; i++) {
42
- if (source[i] > target[i]) {
43
- return true;
44
- }
45
- if (source[i] < target[i]) {
46
- return false;
47
- }
48
- }
49
- // Versions are equal
50
- return true;
51
- }
52
- /**
53
- * Parse frontmatter from markdown file and extract version
54
- */
55
- function parseVersion(content) {
56
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
57
- if (!frontmatterMatch) {
58
- return null;
59
- }
60
- const frontmatter = frontmatterMatch[1];
61
- const versionMatch = frontmatter.match(/version:\s*([^\n]+)/);
62
- return versionMatch ? versionMatch[1].trim() : null;
63
- }
64
- /**
65
- * Install Claude Commands to ~/.claude/commands/ or .claude/commands/
66
- */
67
- const NewCommand = {
68
- alias: ['commands', 'ic'],
69
- description: 'Installs Claude Custom Commands to ~/.claude/commands/ or .claude/commands/ for Claude Code integration. Use --global for global installation, --project for project-specific installation.',
70
- hidden: false,
71
- name: 'install-commands',
72
- run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
73
- var _a;
74
- // Retrieve the tools we need
75
- const { filesystem, parameters, print: { error, info, spin, success }, prompt, } = toolbox;
76
- try {
77
- // Get the CLI installation directory
78
- const cliRoot = (0, path_1.join)(__dirname, '..', '..');
79
- const commandsTemplateDir = (0, path_1.join)(cliRoot, 'templates', 'claude-commands');
80
- // Check if claude-commands directory exists
81
- if (!filesystem.exists(commandsTemplateDir)) {
82
- error('Claude commands directory not found in CLI installation.');
83
- info(`Expected location: ${commandsTemplateDir}`);
84
- info('Please reinstall the CLI or report this issue.');
85
- return;
86
- }
87
- // Get all available commands (*.md files, excluding README.md)
88
- const allFiles = filesystem.list(commandsTemplateDir) || [];
89
- const availableCommands = allFiles.filter(file => file.endsWith('.md') && file !== 'README.md');
90
- if (availableCommands.length === 0) {
91
- error('No commands found in CLI installation.');
92
- return;
93
- }
94
- // Determine installation scope
95
- const cwd = filesystem.cwd();
96
- let scope = 'global';
97
- let commandsDir = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'commands');
98
- const skipInteractive = parameters.options.y || parameters.options.yes || parameters.options['no-interactive'];
99
- // Check if user specified scope
100
- if (parameters.options.global) {
101
- scope = 'global';
102
- commandsDir = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'commands');
103
- }
104
- else if (parameters.options.project) {
105
- scope = 'project';
106
- commandsDir = (0, path_1.join)(cwd, '.claude', 'commands');
107
- }
108
- else {
109
- // Detect if we're in a project
110
- let packageJsonPath = null;
111
- let searchDir = cwd;
112
- // Search up to 3 levels for package.json
113
- for (let i = 0; i < 3; i++) {
114
- const testPath = (0, path_1.join)(searchDir, 'package.json');
115
- if (filesystem.exists(testPath)) {
116
- packageJsonPath = testPath;
117
- break;
118
- }
119
- const parent = (0, path_1.join)(searchDir, '..');
120
- if (parent === searchDir)
121
- break; // Reached root
122
- searchDir = parent;
123
- }
124
- // If in a project, ask where to install
125
- if (packageJsonPath && !skipInteractive) {
126
- info('');
127
- info(`Detected project at: ${searchDir}`);
128
- const installToProject = yield prompt.confirm('Install commands to this project only? (No = install globally for all projects)', false);
129
- scope = installToProject ? 'project' : 'global';
130
- if (scope === 'project') {
131
- commandsDir = (0, path_1.join)(searchDir, '.claude', 'commands');
132
- }
133
- }
134
- else if (packageJsonPath && skipInteractive) {
135
- // In non-interactive mode with project detected, default to global
136
- scope = 'global';
137
- }
138
- }
139
- // Create commands directory if it doesn't exist
140
- if (!filesystem.exists(commandsDir)) {
141
- filesystem.dir(commandsDir);
142
- }
143
- info('');
144
- info('Available commands:');
145
- info('');
146
- // Show all available commands with descriptions
147
- availableCommands.forEach(cmd => {
148
- const cmdPath = (0, path_1.join)(commandsTemplateDir, cmd);
149
- const desc = getCommandDescription(cmdPath, filesystem);
150
- const cmdName = cmd.replace('.md', '');
151
- info(` • /${cmdName}`);
152
- info(` ${desc}`);
153
- info('');
154
- });
155
- let commandsToInstall = [];
156
- // Check if specific commands provided as parameters
157
- if (parameters.first && parameters.first !== 'all') {
158
- // Non-interactive mode: install specific command(s)
159
- const requestedCommands = parameters.array || [parameters.first];
160
- // Add .md extension if not present
161
- const requestedWithExt = requestedCommands.map(c => c.endsWith('.md') ? c : `${c}.md`);
162
- // Validate requested commands
163
- const invalidCommands = requestedWithExt.filter(c => !availableCommands.includes(c));
164
- if (invalidCommands.length > 0) {
165
- error(`Invalid command(s): ${invalidCommands.map(c => c.replace('.md', '')).join(', ')}`);
166
- info('');
167
- info('Available commands:');
168
- availableCommands.forEach(c => {
169
- const cmdName = c.replace('.md', '');
170
- info(` • ${cmdName}`);
171
- });
172
- return;
173
- }
174
- commandsToInstall = requestedWithExt;
175
- }
176
- else if (parameters.first === 'all' || skipInteractive) {
177
- // Install all commands without prompting
178
- commandsToInstall = availableCommands;
179
- if (skipInteractive) {
180
- info('Installing all commands (non-interactive mode)...');
181
- }
182
- }
183
- else {
184
- // Interactive mode: ask if user wants all or select individually
185
- const installAll = yield prompt.confirm('Install all commands?', true);
186
- if (installAll) {
187
- commandsToInstall = availableCommands;
188
- }
189
- else {
190
- // Ask for each command
191
- info('');
192
- info('Select which commands to install:');
193
- info('');
194
- for (const cmd of availableCommands) {
195
- const cmdName = cmd.replace('.md', '');
196
- const shouldInstall = yield prompt.confirm(`Install /${cmdName}?`, true);
197
- if (shouldInstall) {
198
- commandsToInstall.push(cmd);
199
- }
200
- }
201
- if (commandsToInstall.length === 0) {
202
- info('No commands selected. Installation cancelled.');
203
- return;
204
- }
205
- }
206
- }
207
- const installSpinner = spin(`Installing ${commandsToInstall.length} command(s) to ${scope === 'global' ? '~/.claude/commands/' : '.claude/commands/'}...`);
208
- let copiedCount = 0;
209
- let skippedCount = 0;
210
- let updatedCount = 0;
211
- const skippedFiles = [];
212
- // Install each command
213
- for (const cmd of commandsToInstall) {
214
- const sourcePath = (0, path_1.join)(commandsTemplateDir, cmd);
215
- const targetPath = (0, path_1.join)(commandsDir, cmd);
216
- const sourceContent = filesystem.read(sourcePath);
217
- // Check if target file exists
218
- if (filesystem.exists(targetPath)) {
219
- const targetContent = filesystem.read(targetPath);
220
- // Parse versions from both files
221
- const sourceVersion = parseVersion(sourceContent);
222
- const targetVersion = parseVersion(targetContent);
223
- // If both have versions, compare them
224
- if (sourceVersion && targetVersion) {
225
- if (isVersionNewer(sourceVersion, targetVersion)) {
226
- // Source is newer or equal, update
227
- filesystem.write(targetPath, sourceContent);
228
- updatedCount++;
229
- copiedCount++;
230
- }
231
- else {
232
- // Target is newer, skip
233
- skippedCount++;
234
- const reason = `local version ${targetVersion} is newer than ${sourceVersion}`;
235
- skippedFiles.push({ file: cmd, reason });
236
- }
237
- }
238
- else if (sourceVersion && !targetVersion) {
239
- // Source has version, target doesn't - update
240
- filesystem.write(targetPath, sourceContent);
241
- updatedCount++;
242
- copiedCount++;
243
- }
244
- else {
245
- // No version info, always update (backward compatibility)
246
- filesystem.write(targetPath, sourceContent);
247
- updatedCount++;
248
- copiedCount++;
249
- }
250
- }
251
- else {
252
- // Target doesn't exist, create new
253
- filesystem.write(targetPath, sourceContent);
254
- copiedCount++;
255
- }
256
- }
257
- if (copiedCount === 0 && skippedCount === 0) {
258
- installSpinner.fail();
259
- error('No command files were processed.');
260
- return;
261
- }
262
- if (copiedCount === 0 && skippedCount > 0) {
263
- installSpinner.succeed('All selected commands are already up to date!');
264
- info('');
265
- info(`Skipped: ${skippedCount} file(s)`);
266
- info(`Location: ${commandsDir}`);
267
- return;
268
- }
269
- installSpinner.succeed(`Successfully installed ${commandsToInstall.length} command(s)!`);
270
- info('');
271
- if (updatedCount > 0 && skippedCount > 0) {
272
- success(`Updated ${updatedCount} file(s), skipped ${skippedCount} file(s)`);
273
- }
274
- else if (updatedCount > 0) {
275
- success(`Updated ${updatedCount} file(s)`);
276
- }
277
- else {
278
- success(`Created ${copiedCount} file(s)`);
279
- }
280
- info('');
281
- info('Installed commands:');
282
- commandsToInstall.forEach(cmd => {
283
- const cmdPath = (0, path_1.join)(commandsTemplateDir, cmd);
284
- const desc = getCommandDescription(cmdPath, filesystem);
285
- const cmdName = cmd.replace('.md', '');
286
- info(` • /${cmdName}`);
287
- info(` ${desc.substring(0, 80)}${desc.length > 80 ? '...' : ''}`);
288
- });
289
- info('');
290
- info('These commands are now available in Claude Code!');
291
- // Show first installed command as example
292
- const firstCmd = (_a = commandsToInstall[0]) === null || _a === void 0 ? void 0 : _a.replace('.md', '');
293
- info(`Use them by typing the command name with a leading slash, e.g., /${firstCmd || 'command-name'}`);
294
- info('');
295
- info('Examples:');
296
- // Show up to 5 commands as examples (or all if less than 5)
297
- const exampleCount = Math.min(commandsToInstall.length, 5);
298
- for (let i = 0; i < exampleCount; i++) {
299
- const cmd = commandsToInstall[i];
300
- const cmdPath = (0, path_1.join)(commandsTemplateDir, cmd);
301
- const desc = getCommandDescription(cmdPath, filesystem);
302
- const cmdName = cmd.replace('.md', '');
303
- info(` • /${cmdName} - ${desc}`);
304
- }
305
- info('');
306
- info(`Location: ${commandsDir}`);
307
- info(`Scope: ${scope === 'global' ? 'Global (all projects)' : 'Project-specific'}`);
308
- if (skippedCount > 0) {
309
- info('');
310
- info(`Note: ${skippedCount} file(s) were skipped because your local versions are newer:`);
311
- skippedFiles.forEach(({ file, reason }) => {
312
- info(` • ${file} (${reason})`);
313
- });
314
- info('');
315
- info('To force update, manually delete the files and run this command again.');
316
- }
317
- }
318
- catch (err) {
319
- error(`Failed to install command(s): ${err.message}`);
320
- info('');
321
- info('Troubleshooting:');
322
- info(' • Ensure .claude directory exists and is writable');
323
- info(' • Check file permissions');
324
- info(' • Try running with sudo if permission issues persist');
325
- // IMPORTANT: Must call process.exit() to properly close readline stream and terminate the process
326
- // Without this, the command will hang after completion
327
- process.exit(1);
328
- }
329
- // IMPORTANT: Must call process.exit() to properly close readline stream and terminate the process
330
- // This is required when the command doesn't have additional prompts at the end
331
- // (like install-skills does). Without this explicit exit, the readline stream remains open
332
- // and the process hangs indefinitely.
333
- process.exit(0);
334
- }),
335
- };
336
- exports.default = NewCommand;
337
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC1jb21tYW5kcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9jbGF1ZGUvaW5zdGFsbC1jb21tYW5kcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUNBLDJCQUE2QjtBQUM3QiwrQkFBNEI7QUFJNUI7O0dBRUc7QUFDSCxTQUFTLHFCQUFxQixDQUFDLFdBQW1CLEVBQUUsVUFBZTtJQUNqRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sMEJBQTBCLENBQUM7SUFDcEMsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDN0MsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFDaEUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDdEIsT0FBTywwQkFBMEIsQ0FBQztJQUNwQyxDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEMsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBRS9ELE9BQU8sU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLDBCQUEwQixDQUFDO0FBQ3RFLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLGNBQWMsQ0FBQyxhQUFxQixFQUFFLGFBQXFCO0lBQ2xFLE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBZSxFQUFZLEVBQUU7UUFDaEQsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQyxDQUFDO0lBRUYsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUUxQyw4QkFBOEI7SUFDOUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzNCLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzFCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzFCLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRCxxQkFBcUI7SUFDckIsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxPQUFlO0lBQ25DLE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQ2hFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3RCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sWUFBWSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUU5RCxPQUFPLFlBQVksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDdEQsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEdBQW1CO0lBQ2pDLEtBQUssRUFBRSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUM7SUFDekIsV0FBVyxFQUFFLDZMQUE2TDtJQUMxTSxNQUFNLEVBQUUsS0FBSztJQUNiLElBQUksRUFBRSxrQkFBa0I7SUFDeEIsR0FBRyxFQUFFLENBQU8sT0FBK0IsRUFBRSxFQUFFOztRQUM3Qyw2QkFBNkI7UUFDN0IsTUFBTSxFQUNKLFVBQVUsRUFDVixVQUFVLEVBQ1YsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEVBQ3JDLE1BQU0sR0FDUCxHQUFHLE9BQU8sQ0FBQztRQUVaLElBQUksQ0FBQztZQUNILHFDQUFxQztZQUNyQyxNQUFNLE9BQU8sR0FBRyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzVDLE1BQU0sbUJBQW1CLEdBQUcsSUFBQSxXQUFJLEVBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBRTFFLDRDQUE0QztZQUM1QyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUM7Z0JBQzVDLEtBQUssQ0FBQywwREFBMEQsQ0FBQyxDQUFDO2dCQUNsRSxJQUFJLENBQUMsc0JBQXNCLG1CQUFtQixFQUFFLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLGdEQUFnRCxDQUFDLENBQUM7Z0JBQ3ZELE9BQU87WUFDVCxDQUFDO1lBRUQsK0RBQStEO1lBQy9ELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDNUQsTUFBTSxpQkFBaUIsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQy9DLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxLQUFLLFdBQVcsQ0FDN0MsQ0FBQztZQUVGLElBQUksaUJBQWlCLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNuQyxLQUFLLENBQUMsd0NBQXdDLENBQUMsQ0FBQztnQkFDaEQsT0FBTztZQUNULENBQUM7WUFFRCwrQkFBK0I7WUFDL0IsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQzdCLElBQUksS0FBSyxHQUF5QixRQUFRLENBQUM7WUFDM0MsSUFBSSxXQUFXLEdBQUcsSUFBQSxXQUFJLEVBQUMsSUFBQSxZQUFPLEdBQUUsRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDekQsTUFBTSxlQUFlLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRS9HLGdDQUFnQztZQUNoQyxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzlCLEtBQUssR0FBRyxRQUFRLENBQUM7Z0JBQ2pCLFdBQVcsR0FBRyxJQUFBLFdBQUksRUFBQyxJQUFBLFlBQU8sR0FBRSxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN2RCxDQUFDO2lCQUFNLElBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDdEMsS0FBSyxHQUFHLFNBQVMsQ0FBQztnQkFDbEIsV0FBVyxHQUFHLElBQUEsV0FBSSxFQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDakQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLCtCQUErQjtnQkFDL0IsSUFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDO2dCQUMzQixJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUM7Z0JBRXBCLHlDQUF5QztnQkFDekMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUMzQixNQUFNLFFBQVEsR0FBRyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLENBQUM7b0JBQ2pELElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO3dCQUNoQyxlQUFlLEdBQUcsUUFBUSxDQUFDO3dCQUMzQixNQUFNO29CQUNSLENBQUM7b0JBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBQSxXQUFJLEVBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO29CQUNyQyxJQUFJLE1BQU0sS0FBSyxTQUFTO3dCQUFFLE1BQU0sQ0FBQyxlQUFlO29CQUNoRCxTQUFTLEdBQUcsTUFBTSxDQUFDO2dCQUNyQixDQUFDO2dCQUVELHdDQUF3QztnQkFDeEMsSUFBSSxlQUFlLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDeEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUNULElBQUksQ0FBQyx3QkFBd0IsU0FBUyxFQUFFLENBQUMsQ0FBQztvQkFDMUMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQzNDLGlGQUFpRixFQUNqRixLQUFLLENBQ04sQ0FBQztvQkFFRixLQUFLLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO29CQUVoRCxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQzt3QkFDeEIsV0FBVyxHQUFHLElBQUEsV0FBSSxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7b0JBQ3ZELENBQUM7Z0JBQ0gsQ0FBQztxQkFBTSxJQUFJLGVBQWUsSUFBSSxlQUFlLEVBQUUsQ0FBQztvQkFDOUMsbUVBQW1FO29CQUNuRSxLQUFLLEdBQUcsUUFBUSxDQUFDO2dCQUNuQixDQUFDO1lBQ0gsQ0FBQztZQUVELGdEQUFnRDtZQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO2dCQUNwQyxVQUFVLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzlCLENBQUM7WUFFRCxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDVCxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUM1QixJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFVCxnREFBZ0Q7WUFDaEQsaUJBQWlCLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUM5QixNQUFNLE9BQU8sR0FBRyxJQUFBLFdBQUksRUFBQyxtQkFBbUIsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDL0MsTUFBTSxJQUFJLEdBQUcscUJBQXFCLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUN4RCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLFFBQVEsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDcEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1gsQ0FBQyxDQUFDLENBQUM7WUFFSCxJQUFJLGlCQUFpQixHQUFhLEVBQUUsQ0FBQztZQUVyQyxvREFBb0Q7WUFDcEQsSUFBSSxVQUFVLENBQUMsS0FBSyxJQUFJLFVBQVUsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQ25ELG9EQUFvRDtnQkFDcEQsTUFBTSxpQkFBaUIsR0FBRyxVQUFVLENBQUMsS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUVqRSxtQ0FBbUM7Z0JBQ25DLE1BQU0sZ0JBQWdCLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQ2pELENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDbEMsQ0FBQztnQkFFRiw4QkFBOEI7Z0JBQzlCLE1BQU0sZUFBZSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JGLElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDL0IsS0FBSyxDQUFDLHVCQUF1QixlQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUMxRixJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ1QsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7b0JBQzVCLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRTt3QkFDNUIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7d0JBQ3JDLElBQUksQ0FBQyxPQUFPLE9BQU8sRUFBRSxDQUFDLENBQUM7b0JBQ3pCLENBQUMsQ0FBQyxDQUFDO29CQUNILE9BQU87Z0JBQ1QsQ0FBQztnQkFFRCxpQkFBaUIsR0FBRyxnQkFBZ0IsQ0FBQztZQUN2QyxDQUFDO2lCQUFNLElBQUksVUFBVSxDQUFDLEtBQUssS0FBSyxLQUFLLElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ3pELHlDQUF5QztnQkFDekMsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUM7Z0JBQ3RDLElBQUksZUFBZSxFQUFFLENBQUM7b0JBQ3BCLElBQUksQ0FBQyxtREFBbUQsQ0FBQyxDQUFDO2dCQUM1RCxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGlFQUFpRTtnQkFDakUsTUFBTSxVQUFVLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDLHVCQUF1QixFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUV2RSxJQUFJLFVBQVUsRUFBRSxDQUFDO29CQUNmLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDO2dCQUN4QyxDQUFDO3FCQUFNLENBQUM7b0JBQ04sdUJBQXVCO29CQUN2QixJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ1QsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7b0JBQzFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFFVCxLQUFLLE1BQU0sR0FBRyxJQUFJLGlCQUFpQixFQUFFLENBQUM7d0JBQ3BDLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO3dCQUN2QyxNQUFNLGFBQWEsR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxPQUFPLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQzt3QkFDekUsSUFBSSxhQUFhLEVBQUUsQ0FBQzs0QkFDbEIsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO3dCQUM5QixDQUFDO29CQUNILENBQUM7b0JBRUQsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7d0JBQ25DLElBQUksQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO3dCQUN0RCxPQUFPO29CQUNULENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFFRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxpQkFBaUIsQ0FBQyxNQUFNLGtCQUFrQixLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLEtBQUssQ0FBQyxDQUFDO1lBRTNKLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQztZQUNwQixJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7WUFDckIsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLE1BQU0sWUFBWSxHQUE0QyxFQUFFLENBQUM7WUFFakUsdUJBQXVCO1lBQ3ZCLEtBQUssTUFBTSxHQUFHLElBQUksaUJBQWlCLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxVQUFVLEdBQUcsSUFBQSxXQUFJLEVBQUMsbUJBQW1CLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ2xELE1BQU0sVUFBVSxHQUFHLElBQUEsV0FBSSxFQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFFMUMsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFFbEQsOEJBQThCO2dCQUM5QixJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztvQkFDbEMsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFFbEQsaUNBQWlDO29CQUNqQyxNQUFNLGFBQWEsR0FBRyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7b0JBQ2xELE1BQU0sYUFBYSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztvQkFFbEQsc0NBQXNDO29CQUN0QyxJQUFJLGFBQWEsSUFBSSxhQUFhLEVBQUUsQ0FBQzt3QkFDbkMsSUFBSSxjQUFjLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUM7NEJBQ2pELG1DQUFtQzs0QkFDbkMsVUFBVSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7NEJBQzVDLFlBQVksRUFBRSxDQUFDOzRCQUNmLFdBQVcsRUFBRSxDQUFDO3dCQUNoQixDQUFDOzZCQUFNLENBQUM7NEJBQ04sd0JBQXdCOzRCQUN4QixZQUFZLEVBQUUsQ0FBQzs0QkFDZixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsYUFBYSxrQkFBa0IsYUFBYSxFQUFFLENBQUM7NEJBQy9FLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7d0JBQzNDLENBQUM7b0JBQ0gsQ0FBQzt5QkFBTSxJQUFJLGFBQWEsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO3dCQUMzQyw4Q0FBOEM7d0JBQzlDLFVBQVUsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFDO3dCQUM1QyxZQUFZLEVBQUUsQ0FBQzt3QkFDZixXQUFXLEVBQUUsQ0FBQztvQkFDaEIsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLDBEQUEwRDt3QkFDMUQsVUFBVSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7d0JBQzVDLFlBQVksRUFBRSxDQUFDO3dCQUNmLFdBQVcsRUFBRSxDQUFDO29CQUNoQixDQUFDO2dCQUNILENBQUM7cUJBQU0sQ0FBQztvQkFDTixtQ0FBbUM7b0JBQ25DLFVBQVUsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFDO29CQUM1QyxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLFdBQVcsS0FBSyxDQUFDLElBQUksWUFBWSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUM1QyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3RCLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO2dCQUMxQyxPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksV0FBVyxLQUFLLENBQUMsSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsK0NBQStDLENBQUMsQ0FBQztnQkFDeEUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNULElBQUksQ0FBQyxZQUFZLFlBQVksVUFBVSxDQUFDLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxhQUFhLFdBQVcsRUFBRSxDQUFDLENBQUM7Z0JBQ2pDLE9BQU87WUFDVCxDQUFDO1lBRUQsY0FBYyxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsaUJBQWlCLENBQUMsTUFBTSxjQUFjLENBQUMsQ0FBQztZQUN6RixJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFVCxJQUFJLFlBQVksR0FBRyxDQUFDLElBQUksWUFBWSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN6QyxPQUFPLENBQUMsV0FBVyxZQUFZLHFCQUFxQixZQUFZLFVBQVUsQ0FBQyxDQUFDO1lBQzlFLENBQUM7aUJBQU0sSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxXQUFXLFlBQVksVUFBVSxDQUFDLENBQUM7WUFDN0MsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE9BQU8sQ0FBQyxXQUFXLFdBQVcsVUFBVSxDQUFDLENBQUM7WUFDNUMsQ0FBQztZQUVELElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNULElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBQzVCLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDOUIsTUFBTSxPQUFPLEdBQUcsSUFBQSxXQUFJLEVBQUMsbUJBQW1CLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQy9DLE1BQU0sSUFBSSxHQUFHLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDeEQsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxRQUFRLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdkUsQ0FBQyxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDVCxJQUFJLENBQUMsa0RBQWtELENBQUMsQ0FBQztZQUV6RCwwQ0FBMEM7WUFDMUMsTUFBTSxRQUFRLEdBQUcsTUFBQSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsMENBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMxRCxJQUFJLENBQUMsb0VBQW9FLFFBQVEsSUFBSSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNULElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUVsQiw0REFBNEQ7WUFDNUQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDM0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFlBQVksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUN0QyxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakMsTUFBTSxPQUFPLEdBQUcsSUFBQSxXQUFJLEVBQUMsbUJBQW1CLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQy9DLE1BQU0sSUFBSSxHQUFHLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDeEQsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxRQUFRLE9BQU8sTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3BDLENBQUM7WUFFRCxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDVCxJQUFJLENBQUMsYUFBYSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxVQUFVLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUM7WUFFcEYsSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDVCxJQUFJLENBQUMsU0FBUyxZQUFZLDhEQUE4RCxDQUFDLENBQUM7Z0JBQzFGLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFO29CQUN4QyxJQUFJLENBQUMsT0FBTyxJQUFJLEtBQUssTUFBTSxHQUFHLENBQUMsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNULElBQUksQ0FBQyx3RUFBd0UsQ0FBQyxDQUFDO1lBQ2pGLENBQUM7UUFFSCxDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLEtBQUssQ0FBQyxpQ0FBaUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1QsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLHFEQUFxRCxDQUFDLENBQUM7WUFDNUQsSUFBSSxDQUFDLDRCQUE0QixDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7WUFDL0Qsa0dBQWtHO1lBQ2xHLHVEQUF1RDtZQUN2RCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xCLENBQUM7UUFFRCxrR0FBa0c7UUFDbEcsK0VBQStFO1FBQy9FLDJGQUEyRjtRQUMzRixzQ0FBc0M7UUFDdEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQixDQUFDLENBQUE7Q0FDRixDQUFDO0FBRUYsa0JBQWUsVUFBVSxDQUFDIn0=
@@ -1,258 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const child_process_1 = require("child_process");
13
- const fs_1 = require("fs");
14
- const os_1 = require("os");
15
- const path_1 = require("path");
16
- const mcp_registry_1 = require("../../lib/mcp-registry");
17
- /**
18
- * Find the claude CLI executable path
19
- * Checks common installation locations
20
- */
21
- function findClaudeCli() {
22
- const possiblePaths = [
23
- (0, path_1.join)((0, os_1.homedir)(), '.claude', 'local', 'claude'),
24
- '/usr/local/bin/claude',
25
- '/usr/bin/claude',
26
- ];
27
- for (const p of possiblePaths) {
28
- if ((0, fs_1.existsSync)(p)) {
29
- return p;
30
- }
31
- }
32
- // Try to find via 'which' command
33
- try {
34
- const result = (0, child_process_1.execSync)('which claude', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
35
- const path = result.trim();
36
- if (path && (0, fs_1.existsSync)(path)) {
37
- return path;
38
- }
39
- }
40
- catch (_a) {
41
- // Ignore errors
42
- }
43
- return null;
44
- }
45
- let claudePath = null;
46
- /**
47
- * Get claude CLI path (cached)
48
- */
49
- function getClaudeCli() {
50
- if (claudePath === null) {
51
- claudePath = findClaudeCli();
52
- }
53
- return claudePath;
54
- }
55
- /**
56
- * Install an MCP using claude mcp add command
57
- */
58
- function installMcp(mcp) {
59
- const cli = getClaudeCli();
60
- if (!cli) {
61
- return { error: 'Claude CLI not found', success: false };
62
- }
63
- try {
64
- // Build the command with optional transport flag for remote MCPs
65
- const transportFlag = mcp.transport ? `--transport ${mcp.transport} ` : '';
66
- const command = `"${cli}" mcp add ${transportFlag}${mcp.command}`;
67
- (0, child_process_1.execSync)(command, { encoding: 'utf-8', shell: '/bin/bash', stdio: 'inherit' });
68
- return { success: true };
69
- }
70
- catch (err) {
71
- return { error: err.message, success: false };
72
- }
73
- }
74
- /**
75
- * Check if an MCP is already installed by checking Claude's MCP list
76
- */
77
- function isMcpInstalled(mcpId) {
78
- const cli = getClaudeCli();
79
- if (!cli)
80
- return false;
81
- try {
82
- const result = (0, child_process_1.execSync)(`"${cli}" mcp list`, { encoding: 'utf-8', shell: '/bin/bash', stdio: ['pipe', 'pipe', 'pipe'] });
83
- return result.includes(mcpId);
84
- }
85
- catch (_a) {
86
- // If command fails, assume not installed
87
- return false;
88
- }
89
- }
90
- /**
91
- * Install Claude MCPs (Model Context Protocol servers)
92
- */
93
- const NewCommand = {
94
- alias: ['mcps', 'im'],
95
- description: 'Installs Claude MCPs (Model Context Protocol servers) for enhanced Claude Code capabilities. Use -y to skip interactive selection and install all MCPs.',
96
- hidden: false,
97
- name: 'install-mcps',
98
- run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
99
- const { parameters, print: { error, info, spin, success, warning }, prompt, } = toolbox;
100
- try {
101
- // Check if claude CLI is available
102
- const cli = getClaudeCli();
103
- if (!cli) {
104
- error('Claude CLI not found. Please install Claude Code first.');
105
- info('');
106
- info('Installation: https://docs.anthropic.com/en/docs/claude-code');
107
- return;
108
- }
109
- const availableMcps = (0, mcp_registry_1.getAllMcps)();
110
- if (availableMcps.length === 0) {
111
- error('No MCPs defined in registry.');
112
- info('Add MCPs to src/commands/claude/mcp-registry.ts');
113
- return;
114
- }
115
- const skipInteractive = parameters.options.y || parameters.options.yes || parameters.options['no-interactive'];
116
- // Show available MCPs
117
- info('');
118
- info('Available MCPs (Model Context Protocol servers):');
119
- info('');
120
- for (const mcp of availableMcps) {
121
- const installed = isMcpInstalled(mcp.id);
122
- const statusIcon = installed ? '✓' : '○';
123
- const statusText = installed ? ' (installed)' : '';
124
- info(` ${statusIcon} ${mcp.name}${statusText}`);
125
- info(` ${mcp.description}`);
126
- if (mcp.category) {
127
- info(` Category: ${mcp.category}`);
128
- }
129
- info('');
130
- }
131
- let mcpsToInstall = [];
132
- // Check if specific MCPs provided as parameters
133
- if (parameters.first && parameters.first !== 'all') {
134
- // Non-interactive mode: install specific MCP(s)
135
- const requestedMcps = parameters.array || [parameters.first];
136
- // Validate requested MCPs
137
- const invalidMcps = [];
138
- const validMcps = [];
139
- for (const mcpId of requestedMcps) {
140
- const mcp = (0, mcp_registry_1.getMcpById)(mcpId);
141
- if (mcp) {
142
- validMcps.push(mcp);
143
- }
144
- else {
145
- invalidMcps.push(mcpId);
146
- }
147
- }
148
- if (invalidMcps.length > 0) {
149
- error(`Invalid MCP(s): ${invalidMcps.join(', ')}`);
150
- info('');
151
- info('Available MCPs:');
152
- availableMcps.forEach(m => {
153
- info(` • ${m.id} - ${m.name}`);
154
- });
155
- return;
156
- }
157
- mcpsToInstall = validMcps;
158
- }
159
- else if (parameters.first === 'all' || skipInteractive) {
160
- // Install all MCPs without prompting
161
- mcpsToInstall = availableMcps;
162
- if (skipInteractive) {
163
- info('Installing all MCPs (non-interactive mode)...');
164
- }
165
- }
166
- else {
167
- // Interactive mode: ask for each MCP
168
- const installAll = yield prompt.confirm('Install all MCPs?', true);
169
- if (installAll) {
170
- mcpsToInstall = availableMcps;
171
- }
172
- else {
173
- info('');
174
- info('Select which MCPs to install:');
175
- info('');
176
- for (const mcp of availableMcps) {
177
- const installed = isMcpInstalled(mcp.id);
178
- if (installed) {
179
- info(` ✓ ${mcp.name} is already installed, skipping...`);
180
- continue;
181
- }
182
- const shouldInstall = yield prompt.confirm(`Install ${mcp.name}?`, true);
183
- if (shouldInstall) {
184
- mcpsToInstall.push(mcp);
185
- }
186
- }
187
- if (mcpsToInstall.length === 0) {
188
- info('No MCPs selected. Installation cancelled.');
189
- return;
190
- }
191
- }
192
- }
193
- // Filter out already installed MCPs
194
- const notInstalled = mcpsToInstall.filter(mcp => !isMcpInstalled(mcp.id));
195
- const alreadyInstalled = mcpsToInstall.filter(mcp => isMcpInstalled(mcp.id));
196
- if (alreadyInstalled.length > 0) {
197
- info('');
198
- info('Already installed:');
199
- alreadyInstalled.forEach(mcp => {
200
- info(` ✓ ${mcp.name}`);
201
- });
202
- }
203
- if (notInstalled.length === 0) {
204
- info('');
205
- success('All selected MCPs are already installed!');
206
- return;
207
- }
208
- info('');
209
- const installSpinner = spin(`Installing ${notInstalled.length} MCP(s)...`);
210
- installSpinner.stop();
211
- let installedCount = 0;
212
- let failedCount = 0;
213
- const failedMcps = [];
214
- for (const mcp of notInstalled) {
215
- info('');
216
- info(`Installing ${mcp.name}...`);
217
- const result = installMcp(mcp);
218
- if (result.success) {
219
- success(` ✓ ${mcp.name} installed successfully`);
220
- installedCount++;
221
- }
222
- else {
223
- warning(` ✗ Failed to install ${mcp.name}`);
224
- failedMcps.push({ error: result.error || 'Unknown error', mcp });
225
- failedCount++;
226
- }
227
- }
228
- info('');
229
- if (installedCount > 0) {
230
- success(`Successfully installed ${installedCount} MCP(s)!`);
231
- }
232
- if (failedCount > 0) {
233
- warning(`Failed to install ${failedCount} MCP(s):`);
234
- failedMcps.forEach(({ error: err, mcp }) => {
235
- info(` • ${mcp.name}: ${err}`);
236
- });
237
- }
238
- info('');
239
- info('MCPs are now available in Claude Code!');
240
- info('');
241
- info('Manage MCPs with:');
242
- info(' • claude mcp list - List installed MCPs');
243
- info(' • claude mcp remove - Remove an MCP');
244
- }
245
- catch (err) {
246
- error(`Failed to install MCP(s): ${err.message}`);
247
- info('');
248
- info('Troubleshooting:');
249
- info(' • Ensure Claude CLI is installed and configured');
250
- info(' • Check your internet connection');
251
- info(' • Try running with sudo if permission issues persist');
252
- process.exit(1);
253
- }
254
- process.exit(0);
255
- }),
256
- };
257
- exports.default = NewCommand;
258
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC1tY3BzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL2NsYXVkZS9pbnN0YWxsLW1jcHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQSxpREFBeUM7QUFDekMsMkJBQWdDO0FBRWhDLDJCQUE2QjtBQUM3QiwrQkFBNEI7QUFHNUIseURBQTBFO0FBRTFFOzs7R0FHRztBQUNILFNBQVMsYUFBYTtJQUNwQixNQUFNLGFBQWEsR0FBRztRQUNwQixJQUFBLFdBQUksRUFBQyxJQUFBLFlBQU8sR0FBRSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDO1FBQzdDLHVCQUF1QjtRQUN2QixpQkFBaUI7S0FDbEIsQ0FBQztJQUVGLEtBQUssTUFBTSxDQUFDLElBQUksYUFBYSxFQUFFLENBQUM7UUFDOUIsSUFBSSxJQUFBLGVBQVUsRUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2xCLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztJQUNILENBQUM7SUFFRCxrQ0FBa0M7SUFDbEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBQSx3QkFBUSxFQUFDLGNBQWMsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEcsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNCLElBQUksSUFBSSxJQUFJLElBQUEsZUFBVSxFQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUFDLFdBQU0sQ0FBQztRQUNQLGdCQUFnQjtJQUNsQixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsSUFBSSxVQUFVLEdBQWtCLElBQUksQ0FBQztBQUVy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