craftdesk 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -0
- package/README.md +1609 -132
- package/dist/commands/add.d.ts +5 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +306 -8
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/convert.d.ts +8 -0
- package/dist/commands/convert.d.ts.map +1 -0
- package/dist/commands/convert.js +146 -0
- package/dist/commands/convert.js.map +1 -0
- package/dist/commands/detect-agents.d.ts +14 -0
- package/dist/commands/detect-agents.d.ts.map +1 -0
- package/dist/commands/detect-agents.js +86 -0
- package/dist/commands/detect-agents.js.map +1 -0
- package/dist/commands/embed.d.ts +14 -0
- package/dist/commands/embed.d.ts.map +1 -0
- package/dist/commands/embed.js +147 -0
- package/dist/commands/embed.js.map +1 -0
- package/dist/commands/info.d.ts +8 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +66 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +8 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts +5 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +24 -4
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +75 -7
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/login.d.ts +8 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +158 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +8 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +51 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/outdated.d.ts +23 -0
- package/dist/commands/outdated.d.ts.map +1 -0
- package/dist/commands/outdated.js +268 -0
- package/dist/commands/outdated.js.map +1 -0
- package/dist/commands/publish.d.ts +8 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +203 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/remove.d.ts +5 -0
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +51 -10
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/search.d.ts +8 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +60 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/setup-multi-agent.d.ts +17 -0
- package/dist/commands/setup-multi-agent.d.ts.map +1 -0
- package/dist/commands/setup-multi-agent.js +188 -0
- package/dist/commands/setup-multi-agent.js.map +1 -0
- package/dist/commands/sync.d.ts +14 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +144 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/unembed.d.ts +14 -0
- package/dist/commands/unembed.d.ts.map +1 -0
- package/dist/commands/unembed.js +96 -0
- package/dist/commands/unembed.js.map +1 -0
- package/dist/commands/update.d.ts +8 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +372 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +14 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +143 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/whoami.d.ts +8 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +58 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/converters/base-converter.d.ts +89 -0
- package/dist/converters/base-converter.d.ts.map +1 -0
- package/dist/converters/base-converter.js +249 -0
- package/dist/converters/base-converter.js.map +1 -0
- package/dist/converters/continue-converter.d.ts +53 -0
- package/dist/converters/continue-converter.d.ts.map +1 -0
- package/dist/converters/continue-converter.js +243 -0
- package/dist/converters/continue-converter.js.map +1 -0
- package/dist/converters/cursor-converter.d.ts +70 -0
- package/dist/converters/cursor-converter.d.ts.map +1 -0
- package/dist/converters/cursor-converter.js +272 -0
- package/dist/converters/cursor-converter.js.map +1 -0
- package/dist/index.js +56 -3
- package/dist/index.js.map +1 -1
- package/dist/services/agent-detector.d.ts +57 -0
- package/dist/services/agent-detector.d.ts.map +1 -0
- package/dist/services/agent-detector.js +146 -0
- package/dist/services/agent-detector.js.map +1 -0
- package/dist/services/config-manager.d.ts +128 -10
- package/dist/services/config-manager.d.ts.map +1 -1
- package/dist/services/config-manager.js +190 -18
- package/dist/services/config-manager.js.map +1 -1
- package/dist/services/converter.d.ts +53 -0
- package/dist/services/converter.d.ts.map +1 -0
- package/dist/services/converter.js +185 -0
- package/dist/services/converter.js.map +1 -0
- package/dist/services/craft-wrapper.d.ts +108 -0
- package/dist/services/craft-wrapper.d.ts.map +1 -0
- package/dist/services/craft-wrapper.js +268 -0
- package/dist/services/craft-wrapper.js.map +1 -0
- package/dist/services/git-resolver.d.ts +9 -3
- package/dist/services/git-resolver.d.ts.map +1 -1
- package/dist/services/git-resolver.js +44 -20
- package/dist/services/git-resolver.js.map +1 -1
- package/dist/services/gitignore-manager.d.ts +74 -0
- package/dist/services/gitignore-manager.d.ts.map +1 -0
- package/dist/services/gitignore-manager.js +188 -0
- package/dist/services/gitignore-manager.js.map +1 -0
- package/dist/services/installer.d.ts +60 -1
- package/dist/services/installer.d.ts.map +1 -1
- package/dist/services/installer.js +295 -20
- package/dist/services/installer.js.map +1 -1
- package/dist/services/multi-agent-sync.d.ts +88 -0
- package/dist/services/multi-agent-sync.d.ts.map +1 -0
- package/dist/services/multi-agent-sync.js +316 -0
- package/dist/services/multi-agent-sync.js.map +1 -0
- package/dist/services/plugin-resolver.d.ts +80 -0
- package/dist/services/plugin-resolver.d.ts.map +1 -0
- package/dist/services/plugin-resolver.js +183 -0
- package/dist/services/plugin-resolver.js.map +1 -0
- package/dist/services/registry-client.d.ts +132 -5
- package/dist/services/registry-client.d.ts.map +1 -1
- package/dist/services/registry-client.js +239 -34
- package/dist/services/registry-client.js.map +1 -1
- package/dist/services/settings-manager.d.ts +151 -0
- package/dist/services/settings-manager.d.ts.map +1 -0
- package/dist/services/settings-manager.js +333 -0
- package/dist/services/settings-manager.js.map +1 -0
- package/dist/types/claude-settings.d.ts +155 -0
- package/dist/types/claude-settings.d.ts.map +1 -0
- package/dist/types/claude-settings.js +20 -0
- package/dist/types/claude-settings.js.map +1 -0
- package/dist/types/converter.d.ts +98 -0
- package/dist/types/converter.d.ts.map +1 -0
- package/dist/types/converter.js +6 -0
- package/dist/types/converter.js.map +1 -0
- package/dist/types/craftdesk-json.d.ts +76 -3
- package/dist/types/craftdesk-json.d.ts.map +1 -1
- package/dist/types/craftdesk-lock.d.ts +62 -1
- package/dist/types/craftdesk-lock.d.ts.map +1 -1
- package/dist/types/multi-agent.d.ts +85 -0
- package/dist/types/multi-agent.d.ts.map +1 -0
- package/dist/types/multi-agent.js +6 -0
- package/dist/types/multi-agent.js.map +1 -0
- package/dist/utils/crypto.d.ts +23 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +52 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/file-system.d.ts +43 -0
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +45 -2
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/logger.d.ts +75 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +76 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/version-utils.d.ts +63 -0
- package/dist/utils/version-utils.d.ts.map +1 -0
- package/dist/utils/version-utils.js +130 -0
- package/dist/utils/version-utils.js.map +1 -0
- package/package.json +36 -9
- package/.claude/settings.local.json +0 -19
- package/.github/workflows/ci.yml +0 -94
- package/API.md +0 -414
- package/TESTING.md +0 -263
- package/dist/commands/config.d.ts +0 -3
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js +0 -56
- package/dist/commands/config.js.map +0 -1
- package/dist/types/config.d.ts +0 -17
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js +0 -3
- package/dist/types/config.js.map +0 -1
- package/docs/DEPENDENCY_RESOLUTION.md +0 -237
- package/examples/craftdesk-all-sources.json +0 -79
- package/examples/craftdesk-git-monorepo.json +0 -41
- package/examples/craftdesk-multi-registry.json +0 -40
- package/examples/craftdesk-with-registries.json +0 -49
- package/examples/simple-craftdesk.json +0 -10
- package/src/commands/add.ts +0 -314
- package/src/commands/init.ts +0 -55
- package/src/commands/install.ts +0 -126
- package/src/commands/list.ts +0 -126
- package/src/commands/remove.ts +0 -82
- package/src/index.ts +0 -56
- package/src/services/config-manager.ts +0 -150
- package/src/services/git-resolver.ts +0 -373
- package/src/services/installer.ts +0 -314
- package/src/services/registry-client.ts +0 -163
- package/src/types/craftdesk-json.ts +0 -53
- package/src/types/craftdesk-lock.ts +0 -38
- package/src/utils/file-system.ts +0 -55
- package/src/utils/logger.ts +0 -82
- package/tests/fixtures/craftdesk-git.json +0 -17
- package/tests/fixtures/craftdesk.json +0 -15
- package/tests/helpers/test-utils.ts +0 -60
- package/tests/integration/init-command.test.ts +0 -70
- package/tests/integration/list-command.test.ts +0 -77
- package/tests/unit/config-manager.test.ts +0 -228
- package/tests/unit/git-resolver.test.ts +0 -303
- package/tests/unit/installer.test.ts +0 -105
- package/tsconfig.json +0 -20
- package/vitest.config.ts +0 -29
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ConverterService = void 0;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const cursor_converter_1 = require("../converters/cursor-converter");
|
|
10
|
+
const continue_converter_1 = require("../converters/continue-converter");
|
|
11
|
+
/**
|
|
12
|
+
* Service for converting crafts between formats
|
|
13
|
+
*/
|
|
14
|
+
class ConverterService {
|
|
15
|
+
/**
|
|
16
|
+
* Create a converter instance for the specified format
|
|
17
|
+
*
|
|
18
|
+
* @param options - Conversion options
|
|
19
|
+
* @returns Converter instance
|
|
20
|
+
* @throws Error if format is not supported
|
|
21
|
+
*/
|
|
22
|
+
createConverter(options) {
|
|
23
|
+
switch (options.format) {
|
|
24
|
+
case 'cursor':
|
|
25
|
+
return new cursor_converter_1.CursorConverter(options);
|
|
26
|
+
case 'cursor-legacy':
|
|
27
|
+
return new cursor_converter_1.CursorLegacyConverter(options);
|
|
28
|
+
case 'continue':
|
|
29
|
+
return new continue_converter_1.ContinueConverter(options);
|
|
30
|
+
default:
|
|
31
|
+
throw new Error(`Unsupported format: ${options.format}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Convert a craft from a directory
|
|
36
|
+
*
|
|
37
|
+
* @param craftDir - Directory containing the craft
|
|
38
|
+
* @param options - Conversion options
|
|
39
|
+
* @returns Conversion result
|
|
40
|
+
*/
|
|
41
|
+
async convertFromDirectory(craftDir, options) {
|
|
42
|
+
// Load craft metadata
|
|
43
|
+
const manifestPath = path_1.default.join(craftDir, 'craftdesk.json');
|
|
44
|
+
if (!await fs_extra_1.default.pathExists(manifestPath)) {
|
|
45
|
+
throw new Error(`No craftdesk.json found in ${craftDir}`);
|
|
46
|
+
}
|
|
47
|
+
const manifest = await fs_extra_1.default.readJSON(manifestPath);
|
|
48
|
+
// Load main content file
|
|
49
|
+
const markerFiles = ['SKILL.md', 'AGENT.md', 'COMMAND.md', 'HOOK.md', 'PLUGIN.md', 'COLLECTION.md'];
|
|
50
|
+
let mainContent = '';
|
|
51
|
+
let foundMarker = false;
|
|
52
|
+
for (const markerFile of markerFiles) {
|
|
53
|
+
const markerPath = path_1.default.join(craftDir, markerFile);
|
|
54
|
+
if (await fs_extra_1.default.pathExists(markerPath)) {
|
|
55
|
+
mainContent = await fs_extra_1.default.readFile(markerPath, 'utf-8');
|
|
56
|
+
foundMarker = true;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (!foundMarker) {
|
|
61
|
+
throw new Error(`No marker file (SKILL.md, AGENT.md, etc.) found in ${craftDir}`);
|
|
62
|
+
}
|
|
63
|
+
// Build craft content
|
|
64
|
+
const craftContent = {
|
|
65
|
+
name: manifest.name,
|
|
66
|
+
type: manifest.type || 'skill',
|
|
67
|
+
description: manifest.description,
|
|
68
|
+
mainContent,
|
|
69
|
+
sections: {},
|
|
70
|
+
examples: []
|
|
71
|
+
};
|
|
72
|
+
// Parse sections and examples
|
|
73
|
+
const converter = this.createConverter(options);
|
|
74
|
+
// BaseConverter has protected methods, accessing directly for internal use
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
|
+
if ('extractAllSections' in converter && typeof converter.extractAllSections === 'function') {
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
craftContent.sections = converter.extractAllSections(mainContent);
|
|
79
|
+
}
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
if ('extractExamples' in converter && typeof converter.extractExamples === 'function') {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
craftContent.examples = converter.extractExamples(mainContent);
|
|
84
|
+
}
|
|
85
|
+
// Convert
|
|
86
|
+
return await converter.convertWithValidation(craftContent);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Convert and write output files
|
|
90
|
+
*
|
|
91
|
+
* @param craftDir - Directory containing the craft
|
|
92
|
+
* @param options - Conversion options
|
|
93
|
+
* @param outputDir - Optional output directory
|
|
94
|
+
* @returns Conversion result
|
|
95
|
+
*/
|
|
96
|
+
async convertAndWrite(craftDir, options, outputDir) {
|
|
97
|
+
const result = await this.convertFromDirectory(craftDir, options);
|
|
98
|
+
if (!result.success) {
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
// Determine output directory
|
|
102
|
+
const converter = this.createConverter(options);
|
|
103
|
+
const finalOutputDir = outputDir || converter.getDefaultOutputDir();
|
|
104
|
+
// Ensure output directory exists
|
|
105
|
+
await fs_extra_1.default.ensureDir(finalOutputDir);
|
|
106
|
+
// Write files
|
|
107
|
+
for (const file of result.files) {
|
|
108
|
+
const filePath = path_1.default.join(finalOutputDir, file.filePath);
|
|
109
|
+
await fs_extra_1.default.ensureDir(path_1.default.dirname(filePath));
|
|
110
|
+
// Handle merge mode
|
|
111
|
+
if (options.mergeMode === 'skip' && await fs_extra_1.default.pathExists(filePath)) {
|
|
112
|
+
result.warnings.push(`Skipped existing file: ${file.filePath}`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (options.mergeMode === 'append' && await fs_extra_1.default.pathExists(filePath)) {
|
|
116
|
+
const existing = await fs_extra_1.default.readFile(filePath, 'utf-8');
|
|
117
|
+
await fs_extra_1.default.writeFile(filePath, existing + '\n\n' + file.content, 'utf-8');
|
|
118
|
+
result.warnings.push(`Appended to existing file: ${file.filePath}`);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
await fs_extra_1.default.writeFile(filePath, file.content, 'utf-8');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Convert all installed crafts
|
|
128
|
+
*
|
|
129
|
+
* @param claudeDir - Claude directory path
|
|
130
|
+
* @param options - Conversion options
|
|
131
|
+
* @param outputDir - Optional output directory
|
|
132
|
+
* @returns Array of craft names with conversion results
|
|
133
|
+
*/
|
|
134
|
+
async convertAllInstalled(claudeDir, options, outputDir) {
|
|
135
|
+
const results = [];
|
|
136
|
+
// Find all craft directories
|
|
137
|
+
const craftTypes = ['skills', 'agents', 'commands', 'hooks', 'plugins', 'collections'];
|
|
138
|
+
for (const typeDir of craftTypes) {
|
|
139
|
+
const typePath = path_1.default.join(claudeDir, typeDir);
|
|
140
|
+
if (!await fs_extra_1.default.pathExists(typePath)) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const crafts = await fs_extra_1.default.readdir(typePath);
|
|
144
|
+
for (const craftName of crafts) {
|
|
145
|
+
const craftDir = path_1.default.join(typePath, craftName);
|
|
146
|
+
const stat = await fs_extra_1.default.stat(craftDir);
|
|
147
|
+
if (!stat.isDirectory()) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const result = await this.convertAndWrite(craftDir, options, outputDir);
|
|
152
|
+
results.push({ craft: craftName, result });
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
results.push({
|
|
156
|
+
craft: craftName,
|
|
157
|
+
result: {
|
|
158
|
+
success: false,
|
|
159
|
+
files: [],
|
|
160
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
161
|
+
warnings: [],
|
|
162
|
+
sourceFormat: 'claude',
|
|
163
|
+
targetFormat: options.format
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return results;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get list of supported formats
|
|
173
|
+
*
|
|
174
|
+
* @returns Array of supported formats with descriptions
|
|
175
|
+
*/
|
|
176
|
+
getSupportedFormats() {
|
|
177
|
+
return [
|
|
178
|
+
{ format: 'cursor', description: 'Cursor .mdc format in .cursor/rules/' },
|
|
179
|
+
{ format: 'cursor-legacy', description: 'Legacy .cursorrules plain text format' },
|
|
180
|
+
{ format: 'continue', description: 'Continue.dev prompts in .continue/prompts/' }
|
|
181
|
+
];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.ConverterService = ConverterService;
|
|
185
|
+
//# sourceMappingURL=converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/services/converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CraftWrapper - Wraps individual crafts as plugins
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Creating plugin structure for individual skills/agents/commands/hooks
|
|
6
|
+
* - Generating .claude-plugin/plugin.json manifest
|
|
7
|
+
* - Generating PLUGIN.md documentation
|
|
8
|
+
* - Copying craft files into plugin structure
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Options for wrapping a craft as a plugin
|
|
12
|
+
*/
|
|
13
|
+
export interface WrapOptions {
|
|
14
|
+
/** Original craft name */
|
|
15
|
+
craftName: string;
|
|
16
|
+
/** Original craft type */
|
|
17
|
+
craftType: 'skill' | 'agent' | 'command' | 'hook';
|
|
18
|
+
/** Original craft path */
|
|
19
|
+
craftPath: string;
|
|
20
|
+
/** Version for wrapped plugin */
|
|
21
|
+
version: string;
|
|
22
|
+
/** Author name */
|
|
23
|
+
author?: string;
|
|
24
|
+
/** Description */
|
|
25
|
+
description?: string;
|
|
26
|
+
/** Expose as tools */
|
|
27
|
+
exposeAsTools?: boolean;
|
|
28
|
+
/** Expose via MCP */
|
|
29
|
+
exposeAsMCP?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Service for wrapping individual crafts as Claude Code plugins
|
|
33
|
+
*
|
|
34
|
+
* Handles creating plugin structure, generating manifests, and managing wrapped crafts
|
|
35
|
+
*/
|
|
36
|
+
export declare class CraftWrapper {
|
|
37
|
+
/**
|
|
38
|
+
* Wrap an individual craft as a plugin
|
|
39
|
+
*
|
|
40
|
+
* @param options - Wrapping configuration
|
|
41
|
+
* @param installDir - Installation directory (.claude)
|
|
42
|
+
* @returns Path to created plugin
|
|
43
|
+
*/
|
|
44
|
+
wrapCraft(options: WrapOptions, installDir?: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Copy craft files to plugin directory
|
|
47
|
+
*
|
|
48
|
+
* @param sourcePath - Source craft directory
|
|
49
|
+
* @param destPath - Destination plugin directory
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
private copyCraftFiles;
|
|
53
|
+
/**
|
|
54
|
+
* Create plugin manifest
|
|
55
|
+
*
|
|
56
|
+
* @param options - Manifest creation options
|
|
57
|
+
* @param options.name - Plugin name
|
|
58
|
+
* @param options.version - Plugin version
|
|
59
|
+
* @param options.author - Plugin author
|
|
60
|
+
* @param options.description - Plugin description
|
|
61
|
+
* @param options.craftName - Original craft name
|
|
62
|
+
* @param options.craftType - Type of craft being wrapped
|
|
63
|
+
* @param options.exposeAsTools - Whether to expose as tools
|
|
64
|
+
* @param options.exposeAsMCP - Whether to expose via MCP
|
|
65
|
+
* @returns The created plugin manifest
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
private createPluginManifest;
|
|
69
|
+
/**
|
|
70
|
+
* Generate PLUGIN.md documentation
|
|
71
|
+
*
|
|
72
|
+
* @param options - Documentation generation options
|
|
73
|
+
* @param options.pluginName - Name of the plugin
|
|
74
|
+
* @param options.craftName - Name of the wrapped craft
|
|
75
|
+
* @param options.craftType - Type of craft being wrapped
|
|
76
|
+
* @param options.description - Plugin description
|
|
77
|
+
* @param options.version - Plugin version
|
|
78
|
+
* @returns Generated markdown documentation
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
private generatePluginDoc;
|
|
82
|
+
/**
|
|
83
|
+
* Get type directory name
|
|
84
|
+
*
|
|
85
|
+
* @param type - The craft type
|
|
86
|
+
* @returns Directory name for the craft type
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
private getTypeDirectory;
|
|
90
|
+
/**
|
|
91
|
+
* Check if a craft is already wrapped
|
|
92
|
+
*
|
|
93
|
+
* @param craftName - Name of the craft to check
|
|
94
|
+
* @param installDir - Installation directory (default: '.claude')
|
|
95
|
+
* @returns True if craft is already wrapped as a plugin
|
|
96
|
+
*/
|
|
97
|
+
isWrapped(craftName: string, installDir?: string): Promise<boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* Unwrap a plugin (convert back to standalone craft)
|
|
100
|
+
*
|
|
101
|
+
* @param pluginName - Name of the plugin to unwrap
|
|
102
|
+
* @param installDir - Installation directory (default: '.claude')
|
|
103
|
+
* @throws Error if plugin manifest not found or plugin is not wrapped
|
|
104
|
+
*/
|
|
105
|
+
unwrapPlugin(pluginName: string, installDir?: string): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
export declare const craftWrapper: CraftWrapper;
|
|
108
|
+
//# sourceMappingURL=craft-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"craft-wrapper.d.ts","sourceRoot":"","sources":["../../src/services/craft-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAElB,0BAA0B;IAC1B,SAAS,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IAElD,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAElB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAEhB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kBAAkB;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,sBAAsB;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,qBAAqB;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB;;;;;;OAMG;IACG,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,GAAE,MAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAmEtF;;;;;;OAMG;YACW,cAAc;IAmB5B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,oBAAoB;IA4D5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,iBAAiB;IAmDzB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;OAMG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAOpF;;;;;;OAMG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CA8BtF;AAGD,eAAO,MAAM,YAAY,cAAqB,CAAC"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CraftWrapper - Wraps individual crafts as plugins
|
|
4
|
+
*
|
|
5
|
+
* Handles:
|
|
6
|
+
* - Creating plugin structure for individual skills/agents/commands/hooks
|
|
7
|
+
* - Generating .claude-plugin/plugin.json manifest
|
|
8
|
+
* - Generating PLUGIN.md documentation
|
|
9
|
+
* - Copying craft files into plugin structure
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.craftWrapper = exports.CraftWrapper = void 0;
|
|
16
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const logger_1 = require("../utils/logger");
|
|
19
|
+
const file_system_1 = require("../utils/file-system");
|
|
20
|
+
/**
|
|
21
|
+
* Service for wrapping individual crafts as Claude Code plugins
|
|
22
|
+
*
|
|
23
|
+
* Handles creating plugin structure, generating manifests, and managing wrapped crafts
|
|
24
|
+
*/
|
|
25
|
+
class CraftWrapper {
|
|
26
|
+
/**
|
|
27
|
+
* Wrap an individual craft as a plugin
|
|
28
|
+
*
|
|
29
|
+
* @param options - Wrapping configuration
|
|
30
|
+
* @param installDir - Installation directory (.claude)
|
|
31
|
+
* @returns Path to created plugin
|
|
32
|
+
*/
|
|
33
|
+
async wrapCraft(options, installDir = '.claude') {
|
|
34
|
+
const { craftName, craftType, craftPath, version, author, description, exposeAsTools, exposeAsMCP } = options;
|
|
35
|
+
// Create plugin directory
|
|
36
|
+
const pluginName = `${craftName}-plugin`;
|
|
37
|
+
const pluginDir = path_1.default.join(installDir, 'plugins', pluginName);
|
|
38
|
+
await (0, file_system_1.ensureDir)(pluginDir);
|
|
39
|
+
// Create plugin structure based on craft type
|
|
40
|
+
const typeDir = this.getTypeDirectory(craftType);
|
|
41
|
+
const craftDestDir = path_1.default.join(pluginDir, typeDir, craftName);
|
|
42
|
+
await (0, file_system_1.ensureDir)(craftDestDir);
|
|
43
|
+
// Copy craft files
|
|
44
|
+
await this.copyCraftFiles(craftPath, craftDestDir);
|
|
45
|
+
// Create .claude-plugin directory and plugin.json manifest
|
|
46
|
+
const claudePluginDir = path_1.default.join(pluginDir, '.claude-plugin');
|
|
47
|
+
await (0, file_system_1.ensureDir)(claudePluginDir);
|
|
48
|
+
const manifest = this.createPluginManifest({
|
|
49
|
+
name: pluginName,
|
|
50
|
+
version,
|
|
51
|
+
author,
|
|
52
|
+
description: description || `Plugin wrapper for ${craftName} ${craftType}`,
|
|
53
|
+
craftName,
|
|
54
|
+
craftType,
|
|
55
|
+
exposeAsTools,
|
|
56
|
+
exposeAsMCP
|
|
57
|
+
});
|
|
58
|
+
await fs_extra_1.default.writeFile(path_1.default.join(claudePluginDir, 'plugin.json'), JSON.stringify(manifest, null, 2), 'utf-8');
|
|
59
|
+
// Create PLUGIN.md documentation
|
|
60
|
+
const pluginDoc = this.generatePluginDoc({
|
|
61
|
+
pluginName,
|
|
62
|
+
craftName,
|
|
63
|
+
craftType,
|
|
64
|
+
description: description || `Plugin wrapper for ${craftName}`,
|
|
65
|
+
version
|
|
66
|
+
});
|
|
67
|
+
await fs_extra_1.default.writeFile(path_1.default.join(pluginDir, 'PLUGIN.md'), pluginDoc, 'utf-8');
|
|
68
|
+
logger_1.logger.info(`Wrapped ${craftType} '${craftName}' as plugin: ${pluginName}`);
|
|
69
|
+
return pluginDir;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Copy craft files to plugin directory
|
|
73
|
+
*
|
|
74
|
+
* @param sourcePath - Source craft directory
|
|
75
|
+
* @param destPath - Destination plugin directory
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
async copyCraftFiles(sourcePath, destPath) {
|
|
79
|
+
try {
|
|
80
|
+
// Copy all files from source craft directory
|
|
81
|
+
await fs_extra_1.default.copy(sourcePath, destPath, {
|
|
82
|
+
overwrite: true,
|
|
83
|
+
filter: (src) => {
|
|
84
|
+
// Skip metadata files
|
|
85
|
+
const basename = path_1.default.basename(src);
|
|
86
|
+
return basename !== '.craftdesk-metadata.json';
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
logger_1.logger.debug(`Copied craft files from ${sourcePath} to ${destPath}`);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
93
|
+
throw new Error(`Failed to copy craft files: ${message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create plugin manifest
|
|
98
|
+
*
|
|
99
|
+
* @param options - Manifest creation options
|
|
100
|
+
* @param options.name - Plugin name
|
|
101
|
+
* @param options.version - Plugin version
|
|
102
|
+
* @param options.author - Plugin author
|
|
103
|
+
* @param options.description - Plugin description
|
|
104
|
+
* @param options.craftName - Original craft name
|
|
105
|
+
* @param options.craftType - Type of craft being wrapped
|
|
106
|
+
* @param options.exposeAsTools - Whether to expose as tools
|
|
107
|
+
* @param options.exposeAsMCP - Whether to expose via MCP
|
|
108
|
+
* @returns The created plugin manifest
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
createPluginManifest(options) {
|
|
112
|
+
const { name, version, author, description, craftName, craftType, exposeAsTools, exposeAsMCP } = options;
|
|
113
|
+
const components = {};
|
|
114
|
+
// Add craft to appropriate component list
|
|
115
|
+
switch (craftType) {
|
|
116
|
+
case 'skill':
|
|
117
|
+
components.skills = [craftName];
|
|
118
|
+
break;
|
|
119
|
+
case 'agent':
|
|
120
|
+
components.agents = [craftName];
|
|
121
|
+
break;
|
|
122
|
+
case 'command':
|
|
123
|
+
components.commands = [craftName];
|
|
124
|
+
break;
|
|
125
|
+
case 'hook':
|
|
126
|
+
components.hooks = [craftName];
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
// Create official Claude Code compliant manifest
|
|
130
|
+
const manifest = {
|
|
131
|
+
name, // Required field
|
|
132
|
+
version,
|
|
133
|
+
description,
|
|
134
|
+
...(author && { author }),
|
|
135
|
+
// CraftDesk-specific: component listing (not part of official spec)
|
|
136
|
+
components,
|
|
137
|
+
// CraftDesk-specific: Metadata for wrapped craft
|
|
138
|
+
wrapped: {
|
|
139
|
+
craftName,
|
|
140
|
+
craftType,
|
|
141
|
+
wrappedAt: new Date().toISOString(),
|
|
142
|
+
exposeAsTools,
|
|
143
|
+
exposeAsMCP
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
return manifest;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Generate PLUGIN.md documentation
|
|
150
|
+
*
|
|
151
|
+
* @param options - Documentation generation options
|
|
152
|
+
* @param options.pluginName - Name of the plugin
|
|
153
|
+
* @param options.craftName - Name of the wrapped craft
|
|
154
|
+
* @param options.craftType - Type of craft being wrapped
|
|
155
|
+
* @param options.description - Plugin description
|
|
156
|
+
* @param options.version - Plugin version
|
|
157
|
+
* @returns Generated markdown documentation
|
|
158
|
+
* @private
|
|
159
|
+
*/
|
|
160
|
+
generatePluginDoc(options) {
|
|
161
|
+
const { pluginName, craftName, craftType, description, version } = options;
|
|
162
|
+
return `# ${pluginName}
|
|
163
|
+
|
|
164
|
+
**Version**: ${version}
|
|
165
|
+
**Type**: Plugin (Wrapped ${craftType})
|
|
166
|
+
|
|
167
|
+
## Description
|
|
168
|
+
|
|
169
|
+
${description}
|
|
170
|
+
|
|
171
|
+
## Contents
|
|
172
|
+
|
|
173
|
+
This plugin wraps the \`${craftName}\` ${craftType} as a standalone plugin.
|
|
174
|
+
|
|
175
|
+
### Components
|
|
176
|
+
|
|
177
|
+
- **${craftType.charAt(0).toUpperCase() + craftType.slice(1)}**: \`${craftName}\`
|
|
178
|
+
|
|
179
|
+
## Installation
|
|
180
|
+
|
|
181
|
+
This plugin was automatically generated by CraftDesk CLI when wrapping an individual ${craftType}.
|
|
182
|
+
|
|
183
|
+
## Usage
|
|
184
|
+
|
|
185
|
+
The wrapped ${craftType} is available as part of this plugin and can be used like any other ${craftType} in Claude Code.
|
|
186
|
+
|
|
187
|
+
### ${craftType === 'skill' ? 'Skill' : craftType === 'agent' ? 'Agent' : craftType === 'command' ? 'Command' : 'Hook'} Reference
|
|
188
|
+
|
|
189
|
+
See the original ${craftType} documentation in the \`${this.getTypeDirectory(craftType)}/${craftName}/\` directory.
|
|
190
|
+
|
|
191
|
+
## Metadata
|
|
192
|
+
|
|
193
|
+
- **Plugin Name**: ${pluginName}
|
|
194
|
+
- **Original ${craftType.charAt(0).toUpperCase() + craftType.slice(1)}**: ${craftName}
|
|
195
|
+
- **Wrapped At**: ${new Date().toISOString()}
|
|
196
|
+
- **CraftDesk Version**: 0.3.0
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
*This is an auto-generated plugin wrapper created by CraftDesk CLI.*
|
|
201
|
+
`;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get type directory name
|
|
205
|
+
*
|
|
206
|
+
* @param type - The craft type
|
|
207
|
+
* @returns Directory name for the craft type
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
getTypeDirectory(type) {
|
|
211
|
+
switch (type) {
|
|
212
|
+
case 'skill':
|
|
213
|
+
return 'skills';
|
|
214
|
+
case 'agent':
|
|
215
|
+
return 'agents';
|
|
216
|
+
case 'command':
|
|
217
|
+
return 'commands';
|
|
218
|
+
case 'hook':
|
|
219
|
+
return 'hooks';
|
|
220
|
+
default:
|
|
221
|
+
return 'crafts';
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Check if a craft is already wrapped
|
|
226
|
+
*
|
|
227
|
+
* @param craftName - Name of the craft to check
|
|
228
|
+
* @param installDir - Installation directory (default: '.claude')
|
|
229
|
+
* @returns True if craft is already wrapped as a plugin
|
|
230
|
+
*/
|
|
231
|
+
async isWrapped(craftName, installDir = '.claude') {
|
|
232
|
+
const pluginName = `${craftName}-plugin`;
|
|
233
|
+
const pluginDir = path_1.default.join(installDir, 'plugins', pluginName);
|
|
234
|
+
return fs_extra_1.default.pathExists(pluginDir);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Unwrap a plugin (convert back to standalone craft)
|
|
238
|
+
*
|
|
239
|
+
* @param pluginName - Name of the plugin to unwrap
|
|
240
|
+
* @param installDir - Installation directory (default: '.claude')
|
|
241
|
+
* @throws Error if plugin manifest not found or plugin is not wrapped
|
|
242
|
+
*/
|
|
243
|
+
async unwrapPlugin(pluginName, installDir = '.claude') {
|
|
244
|
+
const pluginDir = path_1.default.join(installDir, 'plugins', pluginName);
|
|
245
|
+
// Read plugin manifest to get wrapped craft info
|
|
246
|
+
const manifestPath = path_1.default.join(pluginDir, '.claude-plugin', 'plugin.json');
|
|
247
|
+
if (!await fs_extra_1.default.pathExists(manifestPath)) {
|
|
248
|
+
throw new Error(`Plugin manifest not found: ${pluginName}`);
|
|
249
|
+
}
|
|
250
|
+
const manifest = JSON.parse(await fs_extra_1.default.readFile(manifestPath, 'utf-8'));
|
|
251
|
+
if (!manifest.wrapped) {
|
|
252
|
+
throw new Error(`Plugin ${pluginName} is not a wrapped craft`);
|
|
253
|
+
}
|
|
254
|
+
const { craftName, craftType } = manifest.wrapped;
|
|
255
|
+
// Copy craft back to original location
|
|
256
|
+
const typeDir = this.getTypeDirectory(craftType);
|
|
257
|
+
const craftSourceDir = path_1.default.join(pluginDir, typeDir, craftName);
|
|
258
|
+
const craftDestDir = path_1.default.join(installDir, typeDir, craftName);
|
|
259
|
+
await fs_extra_1.default.copy(craftSourceDir, craftDestDir, { overwrite: true });
|
|
260
|
+
// Remove plugin directory
|
|
261
|
+
await fs_extra_1.default.remove(pluginDir);
|
|
262
|
+
logger_1.logger.info(`Unwrapped plugin ${pluginName} back to ${craftType}: ${craftName}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
exports.CraftWrapper = CraftWrapper;
|
|
266
|
+
// Export singleton instance
|
|
267
|
+
exports.craftWrapper = new CraftWrapper();
|
|
268
|
+
//# sourceMappingURL=craft-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"craft-wrapper.js","sourceRoot":"","sources":["../../src/services/craft-wrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CraftDeskJson, DependencyConfig } from '../types/craftdesk-json';
|
|
2
|
+
import type { LockEntry } from '../types/craftdesk-lock';
|
|
2
3
|
/**
|
|
3
4
|
* Information about a git dependency
|
|
4
5
|
*/
|
|
@@ -97,7 +98,7 @@ export declare class GitResolver {
|
|
|
97
98
|
* Infers the craft type from the repository structure
|
|
98
99
|
*
|
|
99
100
|
* Type inference strategy:
|
|
100
|
-
* 1. Check for marker files: SKILL.md, AGENT.md, COMMAND.md, HOOK.md
|
|
101
|
+
* 1. Check for marker files: SKILL.md, AGENT.md, COMMAND.md, HOOK.md, COLLECTION.md
|
|
101
102
|
* 2. Check directory name for type indicators
|
|
102
103
|
* 3. Default to 'skill' if no indicators found
|
|
103
104
|
*
|
|
@@ -131,8 +132,13 @@ export declare class GitResolver {
|
|
|
131
132
|
* ```
|
|
132
133
|
*/
|
|
133
134
|
resolveAllDependencies(dependencies: Record<string, string | DependencyConfig>): Promise<{
|
|
134
|
-
resolved: Record<string,
|
|
135
|
-
lockfile:
|
|
135
|
+
resolved: Record<string, LockEntry>;
|
|
136
|
+
lockfile: {
|
|
137
|
+
version: string;
|
|
138
|
+
lockfileVersion: number;
|
|
139
|
+
generatedAt: string;
|
|
140
|
+
crafts: Record<string, LockEntry>;
|
|
141
|
+
};
|
|
136
142
|
}>;
|
|
137
143
|
}
|
|
138
144
|
export declare const gitResolver: GitResolver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-resolver.d.ts","sourceRoot":"","sources":["../../src/services/git-resolver.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"git-resolver.d.ts","sourceRoot":"","sources":["../../src/services/git-resolver.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,gCAAgC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;;IAMxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACG,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAuHlF;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,0BAA0B;IAelC;;;;;;;;;;;;OAYG;YACW,cAAc;IA2B5B;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,sBAAsB,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,GAAG,OAAO,CAAC;QAC7F,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACpC,QAAQ,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;SAAE,CAAC;KAChH,CAAC;CA4FH;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|