craftdesk 0.3.0 → 0.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 (175) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +943 -46
  3. package/dist/commands/add.d.ts +5 -0
  4. package/dist/commands/add.d.ts.map +1 -1
  5. package/dist/commands/add.js +302 -6
  6. package/dist/commands/add.js.map +1 -1
  7. package/dist/commands/convert.d.ts +8 -0
  8. package/dist/commands/convert.d.ts.map +1 -0
  9. package/dist/commands/convert.js +146 -0
  10. package/dist/commands/convert.js.map +1 -0
  11. package/dist/commands/info.d.ts +8 -0
  12. package/dist/commands/info.d.ts.map +1 -0
  13. package/dist/commands/info.js +66 -0
  14. package/dist/commands/info.js.map +1 -0
  15. package/dist/commands/init.d.ts +5 -0
  16. package/dist/commands/init.d.ts.map +1 -1
  17. package/dist/commands/init.js +8 -2
  18. package/dist/commands/init.js.map +1 -1
  19. package/dist/commands/install.d.ts +5 -0
  20. package/dist/commands/install.d.ts.map +1 -1
  21. package/dist/commands/install.js +24 -4
  22. package/dist/commands/install.js.map +1 -1
  23. package/dist/commands/list.d.ts +5 -0
  24. package/dist/commands/list.d.ts.map +1 -1
  25. package/dist/commands/list.js +72 -7
  26. package/dist/commands/list.js.map +1 -1
  27. package/dist/commands/login.d.ts +8 -0
  28. package/dist/commands/login.d.ts.map +1 -0
  29. package/dist/commands/login.js +158 -0
  30. package/dist/commands/login.js.map +1 -0
  31. package/dist/commands/logout.d.ts +8 -0
  32. package/dist/commands/logout.d.ts.map +1 -0
  33. package/dist/commands/logout.js +51 -0
  34. package/dist/commands/logout.js.map +1 -0
  35. package/dist/commands/outdated.d.ts +23 -0
  36. package/dist/commands/outdated.d.ts.map +1 -0
  37. package/dist/commands/outdated.js +268 -0
  38. package/dist/commands/outdated.js.map +1 -0
  39. package/dist/commands/publish.d.ts +8 -0
  40. package/dist/commands/publish.d.ts.map +1 -0
  41. package/dist/commands/publish.js +198 -0
  42. package/dist/commands/publish.js.map +1 -0
  43. package/dist/commands/remove.d.ts +5 -0
  44. package/dist/commands/remove.d.ts.map +1 -1
  45. package/dist/commands/remove.js +51 -10
  46. package/dist/commands/remove.js.map +1 -1
  47. package/dist/commands/search.d.ts +8 -0
  48. package/dist/commands/search.d.ts.map +1 -0
  49. package/dist/commands/search.js +60 -0
  50. package/dist/commands/search.js.map +1 -0
  51. package/dist/commands/update.d.ts +8 -0
  52. package/dist/commands/update.d.ts.map +1 -0
  53. package/dist/commands/update.js +369 -0
  54. package/dist/commands/update.js.map +1 -0
  55. package/dist/commands/whoami.d.ts +8 -0
  56. package/dist/commands/whoami.d.ts.map +1 -0
  57. package/dist/commands/whoami.js +58 -0
  58. package/dist/commands/whoami.js.map +1 -0
  59. package/dist/converters/base-converter.d.ts +89 -0
  60. package/dist/converters/base-converter.d.ts.map +1 -0
  61. package/dist/converters/base-converter.js +249 -0
  62. package/dist/converters/base-converter.js.map +1 -0
  63. package/dist/converters/continue-converter.d.ts +53 -0
  64. package/dist/converters/continue-converter.d.ts.map +1 -0
  65. package/dist/converters/continue-converter.js +243 -0
  66. package/dist/converters/continue-converter.js.map +1 -0
  67. package/dist/converters/cursor-converter.d.ts +70 -0
  68. package/dist/converters/cursor-converter.d.ts.map +1 -0
  69. package/dist/converters/cursor-converter.js +272 -0
  70. package/dist/converters/cursor-converter.js.map +1 -0
  71. package/dist/index.js +34 -3
  72. package/dist/index.js.map +1 -1
  73. package/dist/services/config-manager.d.ts +128 -10
  74. package/dist/services/config-manager.d.ts.map +1 -1
  75. package/dist/services/config-manager.js +189 -18
  76. package/dist/services/config-manager.js.map +1 -1
  77. package/dist/services/converter.d.ts +53 -0
  78. package/dist/services/converter.d.ts.map +1 -0
  79. package/dist/services/converter.js +185 -0
  80. package/dist/services/converter.js.map +1 -0
  81. package/dist/services/craft-wrapper.d.ts +108 -0
  82. package/dist/services/craft-wrapper.d.ts.map +1 -0
  83. package/dist/services/craft-wrapper.js +268 -0
  84. package/dist/services/craft-wrapper.js.map +1 -0
  85. package/dist/services/git-resolver.d.ts +9 -3
  86. package/dist/services/git-resolver.d.ts.map +1 -1
  87. package/dist/services/git-resolver.js +29 -10
  88. package/dist/services/git-resolver.js.map +1 -1
  89. package/dist/services/installer.d.ts +51 -1
  90. package/dist/services/installer.d.ts.map +1 -1
  91. package/dist/services/installer.js +245 -14
  92. package/dist/services/installer.js.map +1 -1
  93. package/dist/services/plugin-resolver.d.ts +80 -0
  94. package/dist/services/plugin-resolver.d.ts.map +1 -0
  95. package/dist/services/plugin-resolver.js +182 -0
  96. package/dist/services/plugin-resolver.js.map +1 -0
  97. package/dist/services/registry-client.d.ts +132 -5
  98. package/dist/services/registry-client.d.ts.map +1 -1
  99. package/dist/services/registry-client.js +239 -34
  100. package/dist/services/registry-client.js.map +1 -1
  101. package/dist/services/settings-manager.d.ts +151 -0
  102. package/dist/services/settings-manager.d.ts.map +1 -0
  103. package/dist/services/settings-manager.js +333 -0
  104. package/dist/services/settings-manager.js.map +1 -0
  105. package/dist/types/claude-settings.d.ts +155 -0
  106. package/dist/types/claude-settings.d.ts.map +1 -0
  107. package/dist/types/claude-settings.js +20 -0
  108. package/dist/types/claude-settings.js.map +1 -0
  109. package/dist/types/converter.d.ts +98 -0
  110. package/dist/types/converter.d.ts.map +1 -0
  111. package/dist/types/converter.js +6 -0
  112. package/dist/types/converter.js.map +1 -0
  113. package/dist/types/craftdesk-json.d.ts +63 -3
  114. package/dist/types/craftdesk-json.d.ts.map +1 -1
  115. package/dist/types/craftdesk-lock.d.ts +62 -1
  116. package/dist/types/craftdesk-lock.d.ts.map +1 -1
  117. package/dist/utils/crypto.d.ts +23 -0
  118. package/dist/utils/crypto.d.ts.map +1 -0
  119. package/dist/utils/crypto.js +52 -0
  120. package/dist/utils/crypto.js.map +1 -0
  121. package/dist/utils/file-system.d.ts +43 -0
  122. package/dist/utils/file-system.d.ts.map +1 -1
  123. package/dist/utils/file-system.js +45 -2
  124. package/dist/utils/file-system.js.map +1 -1
  125. package/dist/utils/logger.d.ts +75 -0
  126. package/dist/utils/logger.d.ts.map +1 -1
  127. package/dist/utils/logger.js +76 -1
  128. package/dist/utils/logger.js.map +1 -1
  129. package/dist/utils/version-utils.d.ts +63 -0
  130. package/dist/utils/version-utils.d.ts.map +1 -0
  131. package/dist/utils/version-utils.js +130 -0
  132. package/dist/utils/version-utils.js.map +1 -0
  133. package/package.json +36 -9
  134. package/.claude/settings.local.json +0 -19
  135. package/.github/workflows/ci.yml +0 -94
  136. package/API.md +0 -414
  137. package/TESTING.md +0 -263
  138. package/dist/commands/config.d.ts +0 -3
  139. package/dist/commands/config.d.ts.map +0 -1
  140. package/dist/commands/config.js +0 -56
  141. package/dist/commands/config.js.map +0 -1
  142. package/dist/types/config.d.ts +0 -17
  143. package/dist/types/config.d.ts.map +0 -1
  144. package/dist/types/config.js +0 -3
  145. package/dist/types/config.js.map +0 -1
  146. package/docs/DEPENDENCY_RESOLUTION.md +0 -237
  147. package/examples/craftdesk-all-sources.json +0 -79
  148. package/examples/craftdesk-git-monorepo.json +0 -41
  149. package/examples/craftdesk-multi-registry.json +0 -40
  150. package/examples/craftdesk-with-registries.json +0 -49
  151. package/examples/simple-craftdesk.json +0 -10
  152. package/src/commands/add.ts +0 -314
  153. package/src/commands/init.ts +0 -55
  154. package/src/commands/install.ts +0 -126
  155. package/src/commands/list.ts +0 -126
  156. package/src/commands/remove.ts +0 -82
  157. package/src/index.ts +0 -56
  158. package/src/services/config-manager.ts +0 -150
  159. package/src/services/git-resolver.ts +0 -373
  160. package/src/services/installer.ts +0 -314
  161. package/src/services/registry-client.ts +0 -163
  162. package/src/types/craftdesk-json.ts +0 -53
  163. package/src/types/craftdesk-lock.ts +0 -38
  164. package/src/utils/file-system.ts +0 -55
  165. package/src/utils/logger.ts +0 -82
  166. package/tests/fixtures/craftdesk-git.json +0 -17
  167. package/tests/fixtures/craftdesk.json +0 -15
  168. package/tests/helpers/test-utils.ts +0 -60
  169. package/tests/integration/init-command.test.ts +0 -70
  170. package/tests/integration/list-command.test.ts +0 -77
  171. package/tests/unit/config-manager.test.ts +0 -228
  172. package/tests/unit/git-resolver.test.ts +0 -303
  173. package/tests/unit/installer.test.ts +0 -105
  174. package/tsconfig.json +0 -20
  175. package/vitest.config.ts +0 -29
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.configManager = exports.ConfigManager = void 0;
7
7
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
8
  const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
9
10
  /**
10
11
  * Manages configuration for the CraftDesk CLI
11
12
  *
@@ -21,6 +22,7 @@ const path_1 = __importDefault(require("path"));
21
22
  */
22
23
  class ConfigManager {
23
24
  craftDeskJson = null;
25
+ globalConfig = null;
24
26
  /**
25
27
  * Gets the appropriate registry URL for a given craft
26
28
  *
@@ -53,7 +55,7 @@ class ConfigManager {
53
55
  if (craftName.startsWith('@') && craftDesk.registries) {
54
56
  const scope = craftName.split('/')[0];
55
57
  // Look for a registry with matching scope
56
- for (const [name, registry] of Object.entries(craftDesk.registries)) {
58
+ for (const [_name, registry] of Object.entries(craftDesk.registries)) {
57
59
  if (registry.scope === scope) {
58
60
  return registry.url;
59
61
  }
@@ -67,34 +69,111 @@ class ConfigManager {
67
69
  return 'https://craftdesk.ai';
68
70
  }
69
71
  /**
70
- * Retrieves authentication token for a registry from environment variables
72
+ * Retrieves authentication token for a registry
71
73
  *
72
- * Looks for tokens in environment variables with the pattern:
73
- * CRAFTDESK_AUTH_{REGISTRY_NAME_UPPERCASE}
74
+ * Token precedence (first match wins):
75
+ * 1. Environment variable: CRAFTDESK_AUTH_{REGISTRY_NAME_UPPERCASE}
76
+ * 2. Global config file: ~/.craftdesk/config.json
74
77
  *
75
- * Hyphens in registry names are converted to underscores.
78
+ * Environment variables take precedence to allow CI/CD overrides.
76
79
  *
77
- * @param registryName - The name of the registry from craftdesk.json
80
+ * @param registryUrl - The URL of the registry (e.g., 'https://craftdesk.ai')
78
81
  * @returns The auth token if found, null otherwise
79
82
  *
80
83
  * @example
81
84
  * ```typescript
82
- * // For registry named 'company-private', looks for CRAFTDESK_AUTH_COMPANY_PRIVATE
83
- * const token = await configManager.getAuthToken('company-private');
85
+ * // Check for token (env var or config file)
86
+ * const token = await configManager.getAuthToken('https://craftdesk.ai');
84
87
  *
85
- * // Usage in shell:
86
- * // export CRAFTDESK_AUTH_COMPANY_PRIVATE=token_abc123
88
+ * // Environment variable override:
89
+ * // export CRAFTDESK_AUTH_DEFAULT=token_abc123
87
90
  * ```
88
91
  */
89
- async getAuthToken(registryName) {
92
+ async getAuthToken(registryUrl) {
93
+ // 1. Check environment variable first (for CI/CD overrides)
94
+ const envVar = `CRAFTDESK_AUTH_${this.getRegistryEnvName(registryUrl)}`;
95
+ if (process.env[envVar]) {
96
+ return process.env[envVar] || null;
97
+ }
98
+ // 2. Check global config file
99
+ const config = await this.loadGlobalConfig();
100
+ return config.registries[registryUrl]?.token || null;
101
+ }
102
+ /**
103
+ * Convert registry URL or name to environment variable name suffix
104
+ *
105
+ * @param registryUrl - The registry URL or name to convert
106
+ * @returns Environment variable name suffix (e.g., 'CRAFTDESK_AI')
107
+ * @private
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * // URL to env name
112
+ * getRegistryEnvName('https://craftdesk.ai');
113
+ * // Returns: 'CRAFTDESK_AI'
114
+ *
115
+ * // Registry name to env name
116
+ * getRegistryEnvName('company-private');
117
+ * // Returns: 'COMPANY_PRIVATE'
118
+ * ```
119
+ */
120
+ getRegistryEnvName(registryUrl) {
121
+ try {
122
+ const url = new URL(registryUrl);
123
+ return url.hostname.toUpperCase().replace(/[.-]/g, '_');
124
+ }
125
+ catch {
126
+ // Not a URL - treat as registry name and convert directly
127
+ return registryUrl.toUpperCase().replace(/[.-]/g, '_');
128
+ }
129
+ }
130
+ /**
131
+ * Gets the default registry URL from craftdesk.json
132
+ *
133
+ * @returns The default registry URL, or null if not configured
134
+ */
135
+ async getDefaultRegistry() {
90
136
  const craftDesk = await this.getCraftDeskJson();
91
- if (!craftDesk?.registries?.[registryName]) {
92
- return null;
137
+ return craftDesk?.registries?.default?.url || null;
138
+ }
139
+ /**
140
+ * Resolves a registry identifier to a full URL
141
+ *
142
+ * Handles three cases:
143
+ * 1. Full URL (http:// or https://) - returned as-is
144
+ * 2. Registry name - looked up in craftdesk.json registries section
145
+ * 3. Hostname - prefixed with https://
146
+ *
147
+ * @param registry - A URL, registry name, or hostname
148
+ * @returns The resolved registry URL
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * // Full URL - returned as-is
153
+ * await configManager.resolveRegistryUrl('https://my-registry.com');
154
+ * // Returns: 'https://my-registry.com'
155
+ *
156
+ * // Registry name from craftdesk.json
157
+ * await configManager.resolveRegistryUrl('company-private');
158
+ * // Returns: 'https://company.internal' (from craftdesk.json)
159
+ *
160
+ * // Hostname - prefixed with https://
161
+ * await configManager.resolveRegistryUrl('my-registry.com');
162
+ * // Returns: 'https://my-registry.com'
163
+ * ```
164
+ */
165
+ async resolveRegistryUrl(registry) {
166
+ // If it's already a full URL, use it directly
167
+ if (registry.startsWith('http://') || registry.startsWith('https://')) {
168
+ return registry;
169
+ }
170
+ // Look it up in the craftdesk.json registries section by name
171
+ const craftDeskJson = await this.getCraftDeskJson();
172
+ if (craftDeskJson?.registries?.[registry]) {
173
+ return craftDeskJson.registries[registry].url;
93
174
  }
94
- // Auth tokens should be in environment variables for security
95
- // e.g., CRAFTDESK_AUTH_COMPANY_PRIVATE
96
- const envVar = `CRAFTDESK_AUTH_${registryName.toUpperCase().replace(/-/g, '_')}`;
97
- return process.env[envVar] || null;
175
+ // Assume it's a hostname without protocol
176
+ return `https://${registry}`;
98
177
  }
99
178
  /**
100
179
  * Returns the installation path for crafts
@@ -133,10 +212,102 @@ class ConfigManager {
133
212
  this.craftDeskJson = JSON.parse(content);
134
213
  return this.craftDeskJson;
135
214
  }
136
- catch (error) {
215
+ catch {
137
216
  return null;
138
217
  }
139
218
  }
219
+ // ============================================================
220
+ // Global Configuration Methods (~/.craftdesk/config.json)
221
+ // ============================================================
222
+ /**
223
+ * Gets the path to the global config file
224
+ *
225
+ * @returns Path to ~/.craftdesk/config.json
226
+ */
227
+ getGlobalConfigPath() {
228
+ const home = os_1.default.homedir();
229
+ return path_1.default.join(home, '.craftdesk', 'config.json');
230
+ }
231
+ /**
232
+ * Loads the global configuration from ~/.craftdesk/config.json
233
+ *
234
+ * Returns an empty config if the file doesn't exist
235
+ *
236
+ * @returns The global configuration object
237
+ */
238
+ async loadGlobalConfig() {
239
+ if (this.globalConfig) {
240
+ return this.globalConfig;
241
+ }
242
+ const configPath = this.getGlobalConfigPath();
243
+ try {
244
+ const content = await fs_extra_1.default.readFile(configPath, 'utf-8');
245
+ this.globalConfig = JSON.parse(content);
246
+ return this.globalConfig;
247
+ }
248
+ catch {
249
+ // Return empty config if file doesn't exist
250
+ return { registries: {} };
251
+ }
252
+ }
253
+ /**
254
+ * Saves the global configuration to ~/.craftdesk/config.json
255
+ *
256
+ * Creates the .craftdesk directory if it doesn't exist
257
+ *
258
+ * @param config - The global configuration to save
259
+ */
260
+ async saveGlobalConfig(config) {
261
+ const configPath = this.getGlobalConfigPath();
262
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(configPath));
263
+ await fs_extra_1.default.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
264
+ this.globalConfig = config;
265
+ }
266
+ /**
267
+ * Sets the authentication token for a registry
268
+ * Saves the token and username to the global config file
269
+ *
270
+ * @param registryUrl - The URL of the registry
271
+ * @param token - The API token to store
272
+ * @param username - The username associated with the token
273
+ */
274
+ async setAuthToken(registryUrl, token, username) {
275
+ const config = await this.loadGlobalConfig();
276
+ config.registries[registryUrl] = { token, user: username };
277
+ await this.saveGlobalConfig(config);
278
+ }
279
+ /**
280
+ * Removes the authentication token for a registry
281
+ *
282
+ * @param registryUrl - The URL of the registry to remove auth for
283
+ * @returns true if a token was removed, false if no token existed
284
+ */
285
+ async removeAuthToken(registryUrl) {
286
+ const config = await this.loadGlobalConfig();
287
+ if (config.registries[registryUrl]) {
288
+ delete config.registries[registryUrl];
289
+ await this.saveGlobalConfig(config);
290
+ return true;
291
+ }
292
+ return false;
293
+ }
294
+ /**
295
+ * Gets the stored username for a registry
296
+ *
297
+ * @param registryUrl - The URL of the registry
298
+ * @returns The username if found, null otherwise
299
+ */
300
+ async getStoredUsername(registryUrl) {
301
+ const config = await this.loadGlobalConfig();
302
+ return config.registries[registryUrl]?.user || null;
303
+ }
304
+ /**
305
+ * Clears the cached global config
306
+ * Useful for testing or after external modifications
307
+ */
308
+ clearGlobalConfigCache() {
309
+ this.globalConfig = null;
310
+ }
140
311
  }
141
312
  exports.ConfigManager = ConfigManager;
142
313
  exports.configManager = new ConfigManager();
@@ -1 +1 @@
1
- {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/services/config-manager.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA0B;AAC1B,gDAAwB;AAIxB;;;;;;;;;;;;GAYG;AACH,MAAa,aAAa;IAChB,aAAa,GAAyB,IAAI,CAAC;IAEnD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,mBAAmB,CAAC,SAAiB;QACzC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAEhD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,+CAA+C;YAC/C,OAAO,sBAAsB,CAAC;QAChC,CAAC;QAED,6DAA6D;QAC7D,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAEtC,0CAA0C;YAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpE,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;oBAC7B,OAAO,QAAQ,CAAC,GAAG,CAAC;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;QAED,iDAAiD;QACjD,IAAI,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;YAClC,OAAO,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC;QAC1C,CAAC;QAED,iBAAiB;QACjB,OAAO,sBAAsB,CAAC;IAChC,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,KAAK,CAAC,YAAY,CAAC,YAAoB;QACrC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAEhD,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,8DAA8D;QAC9D,uCAAuC;QACvC,MAAM,MAAM,GAAG,kBAAkB,YAAY,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACjF,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACH,cAAc;QACZ,+CAA+C;QAC/C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,gBAAgB;QACpB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;YACjE,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAC1D,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAjID,sCAiIC;AAEY,QAAA,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/services/config-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { ConversionOptions, ConversionResult, SupportedFormat } from '../types/converter';
2
+ /**
3
+ * Service for converting crafts between formats
4
+ */
5
+ export declare class ConverterService {
6
+ /**
7
+ * Create a converter instance for the specified format
8
+ *
9
+ * @param options - Conversion options
10
+ * @returns Converter instance
11
+ * @throws Error if format is not supported
12
+ */
13
+ private createConverter;
14
+ /**
15
+ * Convert a craft from a directory
16
+ *
17
+ * @param craftDir - Directory containing the craft
18
+ * @param options - Conversion options
19
+ * @returns Conversion result
20
+ */
21
+ convertFromDirectory(craftDir: string, options: ConversionOptions): Promise<ConversionResult>;
22
+ /**
23
+ * Convert and write output files
24
+ *
25
+ * @param craftDir - Directory containing the craft
26
+ * @param options - Conversion options
27
+ * @param outputDir - Optional output directory
28
+ * @returns Conversion result
29
+ */
30
+ convertAndWrite(craftDir: string, options: ConversionOptions, outputDir?: string): Promise<ConversionResult>;
31
+ /**
32
+ * Convert all installed crafts
33
+ *
34
+ * @param claudeDir - Claude directory path
35
+ * @param options - Conversion options
36
+ * @param outputDir - Optional output directory
37
+ * @returns Array of craft names with conversion results
38
+ */
39
+ convertAllInstalled(claudeDir: string, options: ConversionOptions, outputDir?: string): Promise<Array<{
40
+ craft: string;
41
+ result: ConversionResult;
42
+ }>>;
43
+ /**
44
+ * Get list of supported formats
45
+ *
46
+ * @returns Array of supported formats with descriptions
47
+ */
48
+ getSupportedFormats(): Array<{
49
+ format: SupportedFormat;
50
+ description: string;
51
+ }>;
52
+ }
53
+ //# sourceMappingURL=converter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/services/converter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAEhB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,qBAAa,gBAAgB;IAC3B;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;;;OAMG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC;IAuD5B;;;;;;;OAOG;IACG,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,iBAAiB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC;IAqC5B;;;;;;;OAOG;IACG,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC;IA4C9D;;;;OAIG;IACH,mBAAmB,IAAI,KAAK,CAAC;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CAO/E"}
@@ -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":";;;;;;AAAA,wDAA0B;AAC1B,gDAAwB;AAExB,qEAAwF;AACxF,yEAAqE;AASrE;;GAEG;AACH,MAAa,gBAAgB;IAC3B;;;;;;OAMG;IACK,eAAe,CAAC,OAA0B;QAChD,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,QAAQ;gBACX,OAAO,IAAI,kCAAe,CAAC,OAAO,CAAC,CAAC;YAEtC,KAAK,eAAe;gBAClB,OAAO,IAAI,wCAAqB,CAAC,OAAO,CAAC,CAAC;YAE5C,KAAK,UAAU;gBACb,OAAO,IAAI,sCAAiB,CAAC,OAAO,CAAC,CAAC;YAExC;gBACE,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,oBAAoB,CACxB,QAAgB,EAChB,OAA0B;QAE1B,sBAAsB;QACtB,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,kBAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,QAAQ,GAAkB,MAAM,kBAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAEhE,yBAAyB;QACzB,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;QACpG,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,WAAW,GAAG,KAAK,CAAC;QAExB,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACnD,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpC,WAAW,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACrD,WAAW,GAAG,IAAI,CAAC;gBACnB,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,sDAAsD,QAAQ,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,sBAAsB;QACtB,MAAM,YAAY,GAAiB;YACjC,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,OAAO;YAC9B,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,WAAW;YACX,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,EAAE;SACb,CAAC;QAEF,8BAA8B;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChD,2EAA2E;QAC3E,8DAA8D;QAC9D,IAAI,oBAAoB,IAAI,SAAS,IAAI,OAAQ,SAAiB,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YACrG,8DAA8D;YAC9D,YAAY,CAAC,QAAQ,GAAI,SAAiB,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC7E,CAAC;QACD,8DAA8D;QAC9D,IAAI,iBAAiB,IAAI,SAAS,IAAI,OAAQ,SAAiB,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;YAC/F,8DAA8D;YAC9D,YAAY,CAAC,QAAQ,GAAI,SAAiB,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAC1E,CAAC;QAED,UAAU;QACV,OAAO,MAAM,SAAS,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,eAAe,CACnB,QAAgB,EAChB,OAA0B,EAC1B,SAAkB;QAElB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAElE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,6BAA6B;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,cAAc,GAAG,SAAS,IAAI,SAAS,CAAC,mBAAmB,EAAE,CAAC;QAEpE,iCAAiC;QACjC,MAAM,kBAAE,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAEnC,cAAc;QACd,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1D,MAAM,kBAAE,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAE3C,oBAAoB;YACpB,IAAI,OAAO,CAAC,SAAS,KAAK,MAAM,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAClE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAChE,SAAS;YACX,CAAC;YAED,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpE,MAAM,QAAQ,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACtD,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACxE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YACtE,CAAC;iBAAM,CAAC;gBACN,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,mBAAmB,CACvB,SAAiB,EACjB,OAA0B,EAC1B,SAAkB;QAElB,MAAM,OAAO,GAAuD,EAAE,CAAC;QAEvE,6BAA6B;QAC7B,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;QAEvF,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAC/C,IAAI,CAAC,MAAM,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAE1C,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;gBAC/B,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;gBAChD,MAAM,IAAI,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAErC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,SAAS;gBACX,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;oBACxE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC7C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,SAAS;wBAChB,MAAM,EAAE;4BACN,OAAO,EAAE,KAAK;4BACd,KAAK,EAAE,EAAE;4BACT,MAAM,EAAE,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;4BAChE,QAAQ,EAAE,EAAE;4BACZ,YAAY,EAAE,QAAQ;4BACtB,YAAY,EAAE,OAAO,CAAC,MAAM;yBAC7B;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,mBAAmB;QACjB,OAAO;YACL,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;YACzE,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,uCAAuC,EAAE;YACjF,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,4CAA4C,EAAE;SAClF,CAAC;IACJ,CAAC;CACF;AA9MD,4CA8MC"}
@@ -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"}