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.
Files changed (215) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +1609 -132
  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 +306 -8
  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/detect-agents.d.ts +14 -0
  12. package/dist/commands/detect-agents.d.ts.map +1 -0
  13. package/dist/commands/detect-agents.js +86 -0
  14. package/dist/commands/detect-agents.js.map +1 -0
  15. package/dist/commands/embed.d.ts +14 -0
  16. package/dist/commands/embed.d.ts.map +1 -0
  17. package/dist/commands/embed.js +147 -0
  18. package/dist/commands/embed.js.map +1 -0
  19. package/dist/commands/info.d.ts +8 -0
  20. package/dist/commands/info.d.ts.map +1 -0
  21. package/dist/commands/info.js +66 -0
  22. package/dist/commands/info.js.map +1 -0
  23. package/dist/commands/init.d.ts +5 -0
  24. package/dist/commands/init.d.ts.map +1 -1
  25. package/dist/commands/init.js +8 -2
  26. package/dist/commands/init.js.map +1 -1
  27. package/dist/commands/install.d.ts +5 -0
  28. package/dist/commands/install.d.ts.map +1 -1
  29. package/dist/commands/install.js +24 -4
  30. package/dist/commands/install.js.map +1 -1
  31. package/dist/commands/list.d.ts +5 -0
  32. package/dist/commands/list.d.ts.map +1 -1
  33. package/dist/commands/list.js +75 -7
  34. package/dist/commands/list.js.map +1 -1
  35. package/dist/commands/login.d.ts +8 -0
  36. package/dist/commands/login.d.ts.map +1 -0
  37. package/dist/commands/login.js +158 -0
  38. package/dist/commands/login.js.map +1 -0
  39. package/dist/commands/logout.d.ts +8 -0
  40. package/dist/commands/logout.d.ts.map +1 -0
  41. package/dist/commands/logout.js +51 -0
  42. package/dist/commands/logout.js.map +1 -0
  43. package/dist/commands/outdated.d.ts +23 -0
  44. package/dist/commands/outdated.d.ts.map +1 -0
  45. package/dist/commands/outdated.js +268 -0
  46. package/dist/commands/outdated.js.map +1 -0
  47. package/dist/commands/publish.d.ts +8 -0
  48. package/dist/commands/publish.d.ts.map +1 -0
  49. package/dist/commands/publish.js +203 -0
  50. package/dist/commands/publish.js.map +1 -0
  51. package/dist/commands/remove.d.ts +5 -0
  52. package/dist/commands/remove.d.ts.map +1 -1
  53. package/dist/commands/remove.js +51 -10
  54. package/dist/commands/remove.js.map +1 -1
  55. package/dist/commands/search.d.ts +8 -0
  56. package/dist/commands/search.d.ts.map +1 -0
  57. package/dist/commands/search.js +60 -0
  58. package/dist/commands/search.js.map +1 -0
  59. package/dist/commands/setup-multi-agent.d.ts +17 -0
  60. package/dist/commands/setup-multi-agent.d.ts.map +1 -0
  61. package/dist/commands/setup-multi-agent.js +188 -0
  62. package/dist/commands/setup-multi-agent.js.map +1 -0
  63. package/dist/commands/sync.d.ts +14 -0
  64. package/dist/commands/sync.d.ts.map +1 -0
  65. package/dist/commands/sync.js +144 -0
  66. package/dist/commands/sync.js.map +1 -0
  67. package/dist/commands/unembed.d.ts +14 -0
  68. package/dist/commands/unembed.d.ts.map +1 -0
  69. package/dist/commands/unembed.js +96 -0
  70. package/dist/commands/unembed.js.map +1 -0
  71. package/dist/commands/update.d.ts +8 -0
  72. package/dist/commands/update.d.ts.map +1 -0
  73. package/dist/commands/update.js +372 -0
  74. package/dist/commands/update.js.map +1 -0
  75. package/dist/commands/verify.d.ts +14 -0
  76. package/dist/commands/verify.d.ts.map +1 -0
  77. package/dist/commands/verify.js +143 -0
  78. package/dist/commands/verify.js.map +1 -0
  79. package/dist/commands/whoami.d.ts +8 -0
  80. package/dist/commands/whoami.d.ts.map +1 -0
  81. package/dist/commands/whoami.js +58 -0
  82. package/dist/commands/whoami.js.map +1 -0
  83. package/dist/converters/base-converter.d.ts +89 -0
  84. package/dist/converters/base-converter.d.ts.map +1 -0
  85. package/dist/converters/base-converter.js +249 -0
  86. package/dist/converters/base-converter.js.map +1 -0
  87. package/dist/converters/continue-converter.d.ts +53 -0
  88. package/dist/converters/continue-converter.d.ts.map +1 -0
  89. package/dist/converters/continue-converter.js +243 -0
  90. package/dist/converters/continue-converter.js.map +1 -0
  91. package/dist/converters/cursor-converter.d.ts +70 -0
  92. package/dist/converters/cursor-converter.d.ts.map +1 -0
  93. package/dist/converters/cursor-converter.js +272 -0
  94. package/dist/converters/cursor-converter.js.map +1 -0
  95. package/dist/index.js +56 -3
  96. package/dist/index.js.map +1 -1
  97. package/dist/services/agent-detector.d.ts +57 -0
  98. package/dist/services/agent-detector.d.ts.map +1 -0
  99. package/dist/services/agent-detector.js +146 -0
  100. package/dist/services/agent-detector.js.map +1 -0
  101. package/dist/services/config-manager.d.ts +128 -10
  102. package/dist/services/config-manager.d.ts.map +1 -1
  103. package/dist/services/config-manager.js +190 -18
  104. package/dist/services/config-manager.js.map +1 -1
  105. package/dist/services/converter.d.ts +53 -0
  106. package/dist/services/converter.d.ts.map +1 -0
  107. package/dist/services/converter.js +185 -0
  108. package/dist/services/converter.js.map +1 -0
  109. package/dist/services/craft-wrapper.d.ts +108 -0
  110. package/dist/services/craft-wrapper.d.ts.map +1 -0
  111. package/dist/services/craft-wrapper.js +268 -0
  112. package/dist/services/craft-wrapper.js.map +1 -0
  113. package/dist/services/git-resolver.d.ts +9 -3
  114. package/dist/services/git-resolver.d.ts.map +1 -1
  115. package/dist/services/git-resolver.js +44 -20
  116. package/dist/services/git-resolver.js.map +1 -1
  117. package/dist/services/gitignore-manager.d.ts +74 -0
  118. package/dist/services/gitignore-manager.d.ts.map +1 -0
  119. package/dist/services/gitignore-manager.js +188 -0
  120. package/dist/services/gitignore-manager.js.map +1 -0
  121. package/dist/services/installer.d.ts +60 -1
  122. package/dist/services/installer.d.ts.map +1 -1
  123. package/dist/services/installer.js +295 -20
  124. package/dist/services/installer.js.map +1 -1
  125. package/dist/services/multi-agent-sync.d.ts +88 -0
  126. package/dist/services/multi-agent-sync.d.ts.map +1 -0
  127. package/dist/services/multi-agent-sync.js +316 -0
  128. package/dist/services/multi-agent-sync.js.map +1 -0
  129. package/dist/services/plugin-resolver.d.ts +80 -0
  130. package/dist/services/plugin-resolver.d.ts.map +1 -0
  131. package/dist/services/plugin-resolver.js +183 -0
  132. package/dist/services/plugin-resolver.js.map +1 -0
  133. package/dist/services/registry-client.d.ts +132 -5
  134. package/dist/services/registry-client.d.ts.map +1 -1
  135. package/dist/services/registry-client.js +239 -34
  136. package/dist/services/registry-client.js.map +1 -1
  137. package/dist/services/settings-manager.d.ts +151 -0
  138. package/dist/services/settings-manager.d.ts.map +1 -0
  139. package/dist/services/settings-manager.js +333 -0
  140. package/dist/services/settings-manager.js.map +1 -0
  141. package/dist/types/claude-settings.d.ts +155 -0
  142. package/dist/types/claude-settings.d.ts.map +1 -0
  143. package/dist/types/claude-settings.js +20 -0
  144. package/dist/types/claude-settings.js.map +1 -0
  145. package/dist/types/converter.d.ts +98 -0
  146. package/dist/types/converter.d.ts.map +1 -0
  147. package/dist/types/converter.js +6 -0
  148. package/dist/types/converter.js.map +1 -0
  149. package/dist/types/craftdesk-json.d.ts +76 -3
  150. package/dist/types/craftdesk-json.d.ts.map +1 -1
  151. package/dist/types/craftdesk-lock.d.ts +62 -1
  152. package/dist/types/craftdesk-lock.d.ts.map +1 -1
  153. package/dist/types/multi-agent.d.ts +85 -0
  154. package/dist/types/multi-agent.d.ts.map +1 -0
  155. package/dist/types/multi-agent.js +6 -0
  156. package/dist/types/multi-agent.js.map +1 -0
  157. package/dist/utils/crypto.d.ts +23 -0
  158. package/dist/utils/crypto.d.ts.map +1 -0
  159. package/dist/utils/crypto.js +52 -0
  160. package/dist/utils/crypto.js.map +1 -0
  161. package/dist/utils/file-system.d.ts +43 -0
  162. package/dist/utils/file-system.d.ts.map +1 -1
  163. package/dist/utils/file-system.js +45 -2
  164. package/dist/utils/file-system.js.map +1 -1
  165. package/dist/utils/logger.d.ts +75 -0
  166. package/dist/utils/logger.d.ts.map +1 -1
  167. package/dist/utils/logger.js +76 -1
  168. package/dist/utils/logger.js.map +1 -1
  169. package/dist/utils/version-utils.d.ts +63 -0
  170. package/dist/utils/version-utils.d.ts.map +1 -0
  171. package/dist/utils/version-utils.js +130 -0
  172. package/dist/utils/version-utils.js.map +1 -0
  173. package/package.json +36 -9
  174. package/.claude/settings.local.json +0 -19
  175. package/.github/workflows/ci.yml +0 -94
  176. package/API.md +0 -414
  177. package/TESTING.md +0 -263
  178. package/dist/commands/config.d.ts +0 -3
  179. package/dist/commands/config.d.ts.map +0 -1
  180. package/dist/commands/config.js +0 -56
  181. package/dist/commands/config.js.map +0 -1
  182. package/dist/types/config.d.ts +0 -17
  183. package/dist/types/config.d.ts.map +0 -1
  184. package/dist/types/config.js +0 -3
  185. package/dist/types/config.js.map +0 -1
  186. package/docs/DEPENDENCY_RESOLUTION.md +0 -237
  187. package/examples/craftdesk-all-sources.json +0 -79
  188. package/examples/craftdesk-git-monorepo.json +0 -41
  189. package/examples/craftdesk-multi-registry.json +0 -40
  190. package/examples/craftdesk-with-registries.json +0 -49
  191. package/examples/simple-craftdesk.json +0 -10
  192. package/src/commands/add.ts +0 -314
  193. package/src/commands/init.ts +0 -55
  194. package/src/commands/install.ts +0 -126
  195. package/src/commands/list.ts +0 -126
  196. package/src/commands/remove.ts +0 -82
  197. package/src/index.ts +0 -56
  198. package/src/services/config-manager.ts +0 -150
  199. package/src/services/git-resolver.ts +0 -373
  200. package/src/services/installer.ts +0 -314
  201. package/src/services/registry-client.ts +0 -163
  202. package/src/types/craftdesk-json.ts +0 -53
  203. package/src/types/craftdesk-lock.ts +0 -38
  204. package/src/utils/file-system.ts +0 -55
  205. package/src/utils/logger.ts +0 -82
  206. package/tests/fixtures/craftdesk-git.json +0 -17
  207. package/tests/fixtures/craftdesk.json +0 -15
  208. package/tests/helpers/test-utils.ts +0 -60
  209. package/tests/integration/init-command.test.ts +0 -70
  210. package/tests/integration/list-command.test.ts +0 -77
  211. package/tests/unit/config-manager.test.ts +0 -228
  212. package/tests/unit/git-resolver.test.ts +0 -303
  213. package/tests/unit/installer.test.ts +0 -105
  214. package/tsconfig.json +0 -20
  215. package/vitest.config.ts +0 -29
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ /**
3
+ * Multi-Agent Sync - Sync crafts across multiple AI agents
4
+ *
5
+ * Handles:
6
+ * - Installing crafts to multiple agent directories
7
+ * - Verifying sync status with checksums
8
+ * - Detecting and fixing drift between copies
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.multiAgentSync = exports.MultiAgentSync = void 0;
15
+ const fs_extra_1 = __importDefault(require("fs-extra"));
16
+ const path_1 = __importDefault(require("path"));
17
+ const crypto_1 = __importDefault(require("crypto"));
18
+ const logger_1 = require("../utils/logger");
19
+ const config_manager_1 = require("./config-manager");
20
+ const file_system_1 = require("../utils/file-system");
21
+ /**
22
+ * Service for syncing crafts across multiple AI agent directories
23
+ */
24
+ class MultiAgentSync {
25
+ /**
26
+ * Install craft to all configured agent directories
27
+ *
28
+ * @param craftName - Name of the craft to sync
29
+ * @param sourceDir - Source directory containing the craft files
30
+ * @param cwd - Current working directory (defaults to process.cwd())
31
+ * @returns Sync result with success/failure details
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const sync = new MultiAgentSync();
36
+ * const result = await sync.syncCraft('ruby-expert', '/tmp/ruby-expert-source');
37
+ *
38
+ * console.log(`Synced to: ${result.synced.join(', ')}`);
39
+ * if (result.failed.length > 0) {
40
+ * console.error(`Failed: ${result.failed.map(f => f.path).join(', ')}`);
41
+ * }
42
+ * ```
43
+ */
44
+ async syncCraft(craftName, sourceDir, cwd = process.cwd()) {
45
+ const config = await config_manager_1.configManager.getCraftDeskJson();
46
+ // Check if multi-agent sync is enabled
47
+ if (!config?.multiAgent?.enabled) {
48
+ logger_1.logger.debug('Multi-agent sync disabled, skipping');
49
+ return {
50
+ craftName,
51
+ synced: [],
52
+ failed: []
53
+ };
54
+ }
55
+ const canonical = config.multiAgent.canonical || '.claude';
56
+ const targets = config.multiAgent.targets || ['.claude/skills'];
57
+ const synced = [];
58
+ const failed = [];
59
+ // Install to canonical location first
60
+ const canonicalPath = path_1.default.join(cwd, canonical, 'skills', craftName);
61
+ // Normalize paths for comparison
62
+ const normalizedSource = path_1.default.resolve(sourceDir);
63
+ const normalizedCanonical = path_1.default.resolve(canonicalPath);
64
+ try {
65
+ await (0, file_system_1.ensureDir)(path_1.default.dirname(canonicalPath));
66
+ // Only copy if source is different from canonical
67
+ if (normalizedSource !== normalizedCanonical) {
68
+ await fs_extra_1.default.copy(sourceDir, canonicalPath, { overwrite: true });
69
+ logger_1.logger.debug(`Installed to canonical location: ${canonicalPath}`);
70
+ }
71
+ else {
72
+ logger_1.logger.debug(`Source is already canonical: ${canonicalPath}`);
73
+ }
74
+ // Calculate and store checksum
75
+ const checksum = await this.calculateDirChecksum(canonicalPath);
76
+ const checksumFile = path_1.default.join(canonicalPath, '.craftdesk-checksum');
77
+ await fs_extra_1.default.writeFile(checksumFile, checksum, 'utf-8');
78
+ synced.push(canonicalPath);
79
+ }
80
+ catch (error) {
81
+ const message = error instanceof Error ? error.message : String(error);
82
+ failed.push({ path: canonicalPath, error: message });
83
+ logger_1.logger.error(`Failed to install to canonical location: ${message}`);
84
+ // If canonical install fails, don't proceed with targets
85
+ return { craftName, synced, failed };
86
+ }
87
+ // Copy to all target locations
88
+ for (const target of targets) {
89
+ // Skip if target is the canonical location
90
+ if (target === `${canonical}/skills`) {
91
+ continue;
92
+ }
93
+ const targetPath = path_1.default.join(cwd, target, craftName);
94
+ try {
95
+ await (0, file_system_1.ensureDir)(path_1.default.dirname(targetPath));
96
+ await fs_extra_1.default.copy(canonicalPath, targetPath, { overwrite: true });
97
+ synced.push(targetPath);
98
+ logger_1.logger.debug(`Synced ${craftName} to ${target}`);
99
+ }
100
+ catch (error) {
101
+ const message = error instanceof Error ? error.message : String(error);
102
+ failed.push({ path: targetPath, error: message });
103
+ logger_1.logger.warn(`Failed to sync to ${target}: ${message}`);
104
+ }
105
+ }
106
+ logger_1.logger.info(`Synced ${craftName} to ${synced.length} location(s)`);
107
+ return { craftName, synced, failed };
108
+ }
109
+ /**
110
+ * Verify sync status for a craft
111
+ *
112
+ * Checks if all copies match the canonical version using checksums
113
+ *
114
+ * @param craftName - Name of the craft to verify
115
+ * @param cwd - Current working directory (defaults to process.cwd())
116
+ * @returns Sync status with details about each location
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * const sync = new MultiAgentSync();
121
+ * const status = await sync.verifySync('ruby-expert');
122
+ *
123
+ * if (!status.inSync) {
124
+ * console.log(`Out of sync: ${status.outOfSync.map(l => l.path).join(', ')}`);
125
+ * }
126
+ * ```
127
+ */
128
+ async verifySync(craftName, cwd = process.cwd()) {
129
+ const config = await config_manager_1.configManager.getCraftDeskJson();
130
+ if (!config?.multiAgent?.enabled) {
131
+ // If multi-agent not enabled, consider everything in sync
132
+ return {
133
+ craftName,
134
+ inSync: true,
135
+ canonicalChecksum: '',
136
+ outOfSync: [],
137
+ inSyncLocations: []
138
+ };
139
+ }
140
+ const canonical = config.multiAgent.canonical || '.claude';
141
+ const targets = config.multiAgent.targets || [];
142
+ const canonicalPath = path_1.default.join(cwd, canonical, 'skills', craftName);
143
+ // Check if canonical exists
144
+ if (!await fs_extra_1.default.pathExists(canonicalPath)) {
145
+ return {
146
+ craftName,
147
+ inSync: false,
148
+ canonicalChecksum: '',
149
+ outOfSync: [{ path: canonicalPath, reason: 'missing' }],
150
+ inSyncLocations: []
151
+ };
152
+ }
153
+ const canonicalChecksum = await this.calculateDirChecksum(canonicalPath);
154
+ const outOfSync = [];
155
+ const inSyncLocations = [];
156
+ // Check each target
157
+ for (const target of targets) {
158
+ // Skip canonical location
159
+ if (target === `${canonical}/skills`) {
160
+ continue;
161
+ }
162
+ const targetPath = path_1.default.join(cwd, target, craftName);
163
+ // Check if target exists
164
+ if (!await fs_extra_1.default.pathExists(targetPath)) {
165
+ outOfSync.push({
166
+ path: targetPath,
167
+ reason: 'missing',
168
+ expectedChecksum: canonicalChecksum
169
+ });
170
+ continue;
171
+ }
172
+ // Calculate target checksum
173
+ const targetChecksum = await this.calculateDirChecksum(targetPath);
174
+ if (targetChecksum !== canonicalChecksum) {
175
+ outOfSync.push({
176
+ path: targetPath,
177
+ reason: 'checksum-mismatch',
178
+ expectedChecksum: canonicalChecksum,
179
+ actualChecksum: targetChecksum
180
+ });
181
+ }
182
+ else {
183
+ inSyncLocations.push(targetPath);
184
+ }
185
+ }
186
+ return {
187
+ craftName,
188
+ inSync: outOfSync.length === 0,
189
+ canonicalChecksum,
190
+ outOfSync,
191
+ inSyncLocations
192
+ };
193
+ }
194
+ /**
195
+ * Sync all installed crafts to configured targets
196
+ *
197
+ * @param cwd - Current working directory (defaults to process.cwd())
198
+ * @returns Array of sync results for each craft
199
+ */
200
+ async syncAllCrafts(cwd = process.cwd()) {
201
+ const config = await config_manager_1.configManager.getCraftDeskJson();
202
+ if (!config?.multiAgent?.enabled) {
203
+ logger_1.logger.info('Multi-agent sync is disabled');
204
+ return [];
205
+ }
206
+ const canonical = config.multiAgent.canonical || '.claude';
207
+ const skillsDir = path_1.default.join(cwd, canonical, 'skills');
208
+ // Check if skills directory exists
209
+ if (!await fs_extra_1.default.pathExists(skillsDir)) {
210
+ logger_1.logger.info('No skills directory found, nothing to sync');
211
+ return [];
212
+ }
213
+ // Get all craft directories
214
+ const entries = await fs_extra_1.default.readdir(skillsDir, { withFileTypes: true });
215
+ const craftDirs = entries
216
+ .filter(entry => entry.isDirectory())
217
+ .map(entry => entry.name);
218
+ if (craftDirs.length === 0) {
219
+ logger_1.logger.info('No crafts found to sync');
220
+ return [];
221
+ }
222
+ logger_1.logger.info(`Syncing ${craftDirs.length} craft(s)...`);
223
+ const results = [];
224
+ for (const craftName of craftDirs) {
225
+ const craftPath = path_1.default.join(skillsDir, craftName);
226
+ const result = await this.syncCraft(craftName, craftPath, cwd);
227
+ results.push(result);
228
+ }
229
+ return results;
230
+ }
231
+ /**
232
+ * Verify sync status for all installed crafts
233
+ *
234
+ * @param cwd - Current working directory (defaults to process.cwd())
235
+ * @returns Array of sync statuses for each craft
236
+ */
237
+ async verifyAllCrafts(cwd = process.cwd()) {
238
+ const config = await config_manager_1.configManager.getCraftDeskJson();
239
+ if (!config?.multiAgent?.enabled) {
240
+ return [];
241
+ }
242
+ const canonical = config.multiAgent.canonical || '.claude';
243
+ const skillsDir = path_1.default.join(cwd, canonical, 'skills');
244
+ if (!await fs_extra_1.default.pathExists(skillsDir)) {
245
+ return [];
246
+ }
247
+ const entries = await fs_extra_1.default.readdir(skillsDir, { withFileTypes: true });
248
+ const craftDirs = entries
249
+ .filter(entry => entry.isDirectory())
250
+ .map(entry => entry.name);
251
+ const statuses = [];
252
+ for (const craftName of craftDirs) {
253
+ const status = await this.verifySync(craftName, cwd);
254
+ statuses.push(status);
255
+ }
256
+ return statuses;
257
+ }
258
+ /**
259
+ * Calculate checksum for entire directory
260
+ *
261
+ * Creates a consistent hash of all files in a directory (excluding metadata)
262
+ *
263
+ * @param dirPath - Directory to checksum
264
+ * @returns SHA256 checksum hex string
265
+ * @private
266
+ */
267
+ async calculateDirChecksum(dirPath) {
268
+ const files = await this.getAllFiles(dirPath);
269
+ // Sort for consistency
270
+ files.sort();
271
+ const hash = crypto_1.default.createHash('sha256');
272
+ for (const file of files) {
273
+ // Skip metadata files
274
+ const basename = path_1.default.basename(file);
275
+ if (basename === '.craftdesk-checksum' || basename === '.craftdesk-metadata.json') {
276
+ continue;
277
+ }
278
+ // Add relative path to hash
279
+ const relativePath = path_1.default.relative(dirPath, file);
280
+ hash.update(relativePath);
281
+ // Add file content to hash
282
+ const content = await fs_extra_1.default.readFile(file);
283
+ hash.update(content);
284
+ }
285
+ return hash.digest('hex');
286
+ }
287
+ /**
288
+ * Recursively get all files in a directory
289
+ *
290
+ * @param dirPath - Directory to scan
291
+ * @returns Array of absolute file paths
292
+ * @private
293
+ */
294
+ async getAllFiles(dirPath) {
295
+ const files = [];
296
+ if (!await fs_extra_1.default.pathExists(dirPath)) {
297
+ return files;
298
+ }
299
+ const entries = await fs_extra_1.default.readdir(dirPath, { withFileTypes: true });
300
+ for (const entry of entries) {
301
+ const fullPath = path_1.default.join(dirPath, entry.name);
302
+ if (entry.isDirectory()) {
303
+ const subFiles = await this.getAllFiles(fullPath);
304
+ files.push(...subFiles);
305
+ }
306
+ else {
307
+ files.push(fullPath);
308
+ }
309
+ }
310
+ return files;
311
+ }
312
+ }
313
+ exports.MultiAgentSync = MultiAgentSync;
314
+ // Export singleton instance
315
+ exports.multiAgentSync = new MultiAgentSync();
316
+ //# sourceMappingURL=multi-agent-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-agent-sync.js","sourceRoot":"","sources":["../../src/services/multi-agent-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * PluginResolver - Resolves plugin dependencies
3
+ *
4
+ * Handles:
5
+ * - Reading plugin craftdesk.json files
6
+ * - Flattening nested dependencies
7
+ * - Building plugin dependency tree
8
+ * - Detecting circular dependencies
9
+ */
10
+ import type { PluginDependencyTree } from '../types/craftdesk-lock';
11
+ /**
12
+ * Information about a resolved plugin dependency
13
+ */
14
+ export interface ResolvedPlugin {
15
+ name: string;
16
+ version: string;
17
+ dependencies: Record<string, string | import('../types/craftdesk-json').DependencyConfig>;
18
+ isDependency: boolean;
19
+ requiredBy: string[];
20
+ }
21
+ /**
22
+ * Service for resolving plugin dependencies and building dependency trees
23
+ *
24
+ * Handles recursive dependency resolution, circular dependency detection,
25
+ * and flattening nested plugin dependencies
26
+ */
27
+ export declare class PluginResolver {
28
+ private resolvedPlugins;
29
+ private resolutionStack;
30
+ /**
31
+ * Resolve plugin dependencies recursively
32
+ *
33
+ * @param pluginPath - Path to plugin directory
34
+ * @param parentName - Name of parent plugin (for tracking requiredBy)
35
+ * @returns Flattened dependency map
36
+ */
37
+ resolvePluginDependencies(pluginPath: string, parentName?: string): Promise<Record<string, ResolvedPlugin>>;
38
+ /**
39
+ * Build plugin dependency tree for lockfile
40
+ *
41
+ * @returns Plugin dependency tree structure
42
+ */
43
+ buildPluginTree(): PluginDependencyTree;
44
+ /**
45
+ * Get flattened dependencies
46
+ *
47
+ * This is what goes into craftdesk.json
48
+ *
49
+ * @returns Flattened dependency map
50
+ */
51
+ getFlattenedDependencies(): Record<string, string | import('../types/craftdesk-json').DependencyConfig>;
52
+ /**
53
+ * Get only directly installed plugins (not dependencies)
54
+ *
55
+ * @returns Array of directly installed plugins
56
+ */
57
+ getDirectPlugins(): ResolvedPlugin[];
58
+ /**
59
+ * Get only dependency plugins (not directly installed)
60
+ *
61
+ * @returns Array of dependency plugins
62
+ */
63
+ getDependencyPlugins(): ResolvedPlugin[];
64
+ /**
65
+ * Read plugin manifest (craftdesk.json)
66
+ *
67
+ * @param pluginPath - Path to plugin directory
68
+ * @returns Parsed manifest or null if not found
69
+ * @private
70
+ */
71
+ private readPluginManifest;
72
+ /**
73
+ * Reset resolver state
74
+ *
75
+ * Clears all resolved plugins and resolution stack
76
+ */
77
+ reset(): void;
78
+ }
79
+ export declare const pluginResolver: PluginResolver;
80
+ //# sourceMappingURL=plugin-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-resolver.d.ts","sourceRoot":"","sources":["../../src/services/plugin-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,yBAAyB,EAAE,gBAAgB,CAAC,CAAC;IAC1F,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,eAAe,CAAgB;IAEvC;;;;;;OAMG;IACG,yBAAyB,CAC7B,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAkE1C;;;;OAIG;IACH,eAAe,IAAI,oBAAoB;IAevC;;;;;;OAMG;IACH,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,yBAAyB,EAAE,gBAAgB,CAAC;IAoBvG;;;;OAIG;IACH,gBAAgB,IAAI,cAAc,EAAE;IAIpC;;;;OAIG;IACH,oBAAoB,IAAI,cAAc,EAAE;IAIxC;;;;;;OAMG;YACW,kBAAkB;IAgBhC;;;;OAIG;IACH,KAAK,IAAI,IAAI;CAId;AAGD,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ /**
3
+ * PluginResolver - Resolves plugin dependencies
4
+ *
5
+ * Handles:
6
+ * - Reading plugin craftdesk.json files
7
+ * - Flattening nested dependencies
8
+ * - Building plugin dependency tree
9
+ * - Detecting circular dependencies
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.pluginResolver = exports.PluginResolver = 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
+ /**
20
+ * Service for resolving plugin dependencies and building dependency trees
21
+ *
22
+ * Handles recursive dependency resolution, circular dependency detection,
23
+ * and flattening nested plugin dependencies
24
+ */
25
+ class PluginResolver {
26
+ resolvedPlugins = new Map();
27
+ resolutionStack = [];
28
+ /**
29
+ * Resolve plugin dependencies recursively
30
+ *
31
+ * @param pluginPath - Path to plugin directory
32
+ * @param parentName - Name of parent plugin (for tracking requiredBy)
33
+ * @returns Flattened dependency map
34
+ */
35
+ async resolvePluginDependencies(pluginPath, parentName) {
36
+ // Read plugin's craftdesk.json
37
+ const manifest = await this.readPluginManifest(pluginPath);
38
+ if (!manifest) {
39
+ throw new Error(`No craftdesk.json found in plugin: ${pluginPath}`);
40
+ }
41
+ const pluginName = manifest.name;
42
+ // Check for circular dependencies
43
+ if (this.resolutionStack.includes(pluginName)) {
44
+ const cycle = [...this.resolutionStack, pluginName].join(' → ');
45
+ throw new Error(`Circular dependency detected: ${cycle}`);
46
+ }
47
+ // Add to resolution stack
48
+ this.resolutionStack.push(pluginName);
49
+ try {
50
+ // If already resolved, just add requiredBy
51
+ if (this.resolvedPlugins.has(pluginName)) {
52
+ const existing = this.resolvedPlugins.get(pluginName);
53
+ // existing is guaranteed to exist due to has() check above
54
+ if (existing && parentName && !existing.requiredBy.includes(parentName)) {
55
+ existing.requiredBy.push(parentName);
56
+ }
57
+ return Object.fromEntries(this.resolvedPlugins);
58
+ }
59
+ // Create resolved entry
60
+ const resolved = {
61
+ name: pluginName,
62
+ version: manifest.version,
63
+ dependencies: manifest.dependencies || {},
64
+ isDependency: !!parentName,
65
+ requiredBy: parentName ? [parentName] : []
66
+ };
67
+ this.resolvedPlugins.set(pluginName, resolved);
68
+ // Recursively resolve dependencies
69
+ if (manifest.dependencies) {
70
+ for (const [depName, depVersion] of Object.entries(manifest.dependencies)) {
71
+ // Skip if dependency is a string (version) - these are resolved by registry
72
+ if (typeof depVersion === 'string') {
73
+ logger_1.logger.debug(`Dependency ${depName} will be resolved by registry`);
74
+ continue;
75
+ }
76
+ // Handle git dependencies with subdirectories
77
+ if (depVersion.git && depVersion.path) {
78
+ // Dependency is in a subdirectory of git repo - we'll need to clone and resolve
79
+ logger_1.logger.debug(`Dependency ${depName} requires git clone for resolution`);
80
+ continue;
81
+ }
82
+ }
83
+ }
84
+ return Object.fromEntries(this.resolvedPlugins);
85
+ }
86
+ finally {
87
+ // Remove from resolution stack
88
+ this.resolutionStack.pop();
89
+ }
90
+ }
91
+ /**
92
+ * Build plugin dependency tree for lockfile
93
+ *
94
+ * @returns Plugin dependency tree structure
95
+ */
96
+ buildPluginTree() {
97
+ const tree = {};
98
+ for (const [name, plugin] of this.resolvedPlugins) {
99
+ tree[name] = {
100
+ version: plugin.version,
101
+ dependencies: Object.keys(plugin.dependencies),
102
+ isDependency: plugin.isDependency,
103
+ requiredBy: plugin.requiredBy
104
+ };
105
+ }
106
+ return tree;
107
+ }
108
+ /**
109
+ * Get flattened dependencies
110
+ *
111
+ * This is what goes into craftdesk.json
112
+ *
113
+ * @returns Flattened dependency map
114
+ */
115
+ getFlattenedDependencies() {
116
+ const flattened = {};
117
+ for (const [name, plugin] of this.resolvedPlugins) {
118
+ flattened[name] = plugin.version;
119
+ // Add plugin's dependencies
120
+ for (const [depName, depVersion] of Object.entries(plugin.dependencies)) {
121
+ if (typeof depVersion === 'string') {
122
+ flattened[depName] = depVersion;
123
+ }
124
+ else {
125
+ // Complex dependency config - we'll add it as-is
126
+ flattened[depName] = depVersion;
127
+ }
128
+ }
129
+ }
130
+ return flattened;
131
+ }
132
+ /**
133
+ * Get only directly installed plugins (not dependencies)
134
+ *
135
+ * @returns Array of directly installed plugins
136
+ */
137
+ getDirectPlugins() {
138
+ return Array.from(this.resolvedPlugins.values()).filter(p => !p.isDependency);
139
+ }
140
+ /**
141
+ * Get only dependency plugins (not directly installed)
142
+ *
143
+ * @returns Array of dependency plugins
144
+ */
145
+ getDependencyPlugins() {
146
+ return Array.from(this.resolvedPlugins.values()).filter(p => p.isDependency);
147
+ }
148
+ /**
149
+ * Read plugin manifest (craftdesk.json)
150
+ *
151
+ * @param pluginPath - Path to plugin directory
152
+ * @returns Parsed manifest or null if not found
153
+ * @private
154
+ */
155
+ async readPluginManifest(pluginPath) {
156
+ const manifestPath = path_1.default.join(pluginPath, 'craftdesk.json');
157
+ try {
158
+ if (await fs_extra_1.default.pathExists(manifestPath)) {
159
+ const content = await fs_extra_1.default.readFile(manifestPath, 'utf-8');
160
+ return JSON.parse(content);
161
+ }
162
+ return null;
163
+ }
164
+ catch (error) {
165
+ const message = error instanceof Error ? error.message : String(error);
166
+ logger_1.logger.debug(`Failed to read plugin manifest at ${manifestPath}: ${message}`);
167
+ return null;
168
+ }
169
+ }
170
+ /**
171
+ * Reset resolver state
172
+ *
173
+ * Clears all resolved plugins and resolution stack
174
+ */
175
+ reset() {
176
+ this.resolvedPlugins.clear();
177
+ this.resolutionStack = [];
178
+ }
179
+ }
180
+ exports.PluginResolver = PluginResolver;
181
+ // Export singleton instance
182
+ exports.pluginResolver = new PluginResolver();
183
+ //# sourceMappingURL=plugin-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-resolver.js","sourceRoot":"","sources":["../../src/services/plugin-resolver.ts"],"names":[],"mappings":"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"}