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
@@ -0,0 +1,23 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Creates the outdated command for checking newer versions of installed crafts.
4
+ *
5
+ * @returns The configured Commander command instance
6
+ */
7
+ export declare function createOutdatedCommand(): Command;
8
+ /**
9
+ * Exported wrapper for testing - fetches remote git tags from a repository.
10
+ *
11
+ * @param gitUrl - The git repository URL
12
+ * @returns Array of tag names found in the repository
13
+ */
14
+ export declare function getRemoteTagsExported(gitUrl: string): string[];
15
+ /**
16
+ * Exported wrapper for testing - fetches the latest commit hash from a git branch.
17
+ *
18
+ * @param gitUrl - The git repository URL
19
+ * @param branch - The branch name to check
20
+ * @returns The commit hash or null if not found
21
+ */
22
+ export declare function getRemoteHeadCommitExported(gitUrl: string, branch: string): string | null;
23
+ //# sourceMappingURL=outdated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outdated.d.ts","sourceRoot":"","sources":["../../src/commands/outdated.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAS/C;AA0PD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEzF"}
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOutdatedCommand = createOutdatedCommand;
4
+ exports.getRemoteTagsExported = getRemoteTagsExported;
5
+ exports.getRemoteHeadCommitExported = getRemoteHeadCommitExported;
6
+ const commander_1 = require("commander");
7
+ const child_process_1 = require("child_process");
8
+ const file_system_1 = require("../utils/file-system");
9
+ const logger_1 = require("../utils/logger");
10
+ const registry_client_1 = require("../services/registry-client");
11
+ const version_utils_1 = require("../utils/version-utils");
12
+ /**
13
+ * Creates the outdated command for checking newer versions of installed crafts.
14
+ *
15
+ * @returns The configured Commander command instance
16
+ */
17
+ function createOutdatedCommand() {
18
+ return new commander_1.Command('outdated')
19
+ .description('Check for newer versions of installed crafts')
20
+ .option('--json', 'Output as JSON')
21
+ .option('--git-only', 'Only check git-based dependencies')
22
+ .option('--registry-only', 'Only check registry-based dependencies')
23
+ .action(async (options) => {
24
+ await outdatedCommand(options);
25
+ });
26
+ }
27
+ async function outdatedCommand(options) {
28
+ try {
29
+ // Read craftdesk.json for project info
30
+ const craftDeskJson = await (0, file_system_1.readCraftDeskJson)();
31
+ if (!craftDeskJson) {
32
+ logger_1.logger.error('No craftdesk.json found in current directory');
33
+ process.exit(1);
34
+ }
35
+ // Read lockfile to get installed versions
36
+ const lockfile = await (0, file_system_1.readCraftDeskLock)();
37
+ if (!lockfile || !lockfile.crafts || Object.keys(lockfile.crafts).length === 0) {
38
+ logger_1.logger.warn('No crafts installed. Run "craftdesk install" first.');
39
+ process.exit(0);
40
+ }
41
+ if (!options.json) {
42
+ logger_1.logger.info('Checking for updates...\n');
43
+ }
44
+ const outdatedList = [];
45
+ const crafts = lockfile.crafts;
46
+ // Check each installed craft
47
+ for (const [name, entry] of Object.entries(crafts)) {
48
+ const lockEntry = entry;
49
+ // Skip based on options
50
+ if (options.gitOnly && !lockEntry.git)
51
+ continue;
52
+ if (options.registryOnly && lockEntry.git)
53
+ continue;
54
+ try {
55
+ let outdatedInfo = null;
56
+ if (lockEntry.git) {
57
+ // Git-based dependency
58
+ outdatedInfo = await checkGitUpdate(name, lockEntry);
59
+ }
60
+ else {
61
+ // Registry-based dependency
62
+ outdatedInfo = await checkRegistryUpdate(name, lockEntry);
63
+ }
64
+ if (outdatedInfo) {
65
+ outdatedList.push(outdatedInfo);
66
+ }
67
+ }
68
+ catch (error) {
69
+ const message = error instanceof Error ? error.message : String(error);
70
+ logger_1.logger.debug(`Failed to check ${name}: ${message}`);
71
+ }
72
+ }
73
+ // Output results
74
+ if (options.json) {
75
+ console.log(JSON.stringify(outdatedList, null, 2));
76
+ return;
77
+ }
78
+ // Filter to only show crafts with updates
79
+ const withUpdates = outdatedList.filter(o => o.hasUpdate);
80
+ if (withUpdates.length === 0) {
81
+ logger_1.logger.success('All crafts are up to date!');
82
+ return;
83
+ }
84
+ // Display table header
85
+ const nameWidth = Math.max(25, ...withUpdates.map(o => o.name.length + 2));
86
+ const colWidth = 14;
87
+ console.log('');
88
+ console.log((0, version_utils_1.padRight)('Craft', nameWidth) +
89
+ (0, version_utils_1.padRight)('Current', colWidth) +
90
+ (0, version_utils_1.padRight)('Wanted', colWidth) +
91
+ (0, version_utils_1.padRight)('Latest', colWidth) +
92
+ 'Source');
93
+ console.log('-'.repeat(nameWidth + colWidth * 3 + 10));
94
+ // Display each outdated craft
95
+ for (const info of withUpdates) {
96
+ const sourceCol = info.source === 'git' ? 'git' : 'registry';
97
+ // Display with colors (alignment uses plain text)
98
+ console.log((0, version_utils_1.padRight)(info.name, nameWidth) +
99
+ (0, version_utils_1.colorize)((0, version_utils_1.padRight)(info.current, colWidth), 'red') +
100
+ (0, version_utils_1.colorize)((0, version_utils_1.padRight)(info.wanted, colWidth), 'yellow') +
101
+ (0, version_utils_1.colorize)((0, version_utils_1.padRight)(info.latest, colWidth), 'green') +
102
+ sourceCol);
103
+ }
104
+ console.log('');
105
+ logger_1.logger.info(`${withUpdates.length} craft(s) have updates available.`);
106
+ logger_1.logger.info('Run "craftdesk install" to update to wanted versions.');
107
+ logger_1.logger.info('Run "craftdesk add <craft>@latest" to update to latest version.');
108
+ }
109
+ catch (error) {
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ logger_1.logger.error(`Failed to check for updates: ${message}`);
112
+ process.exit(1);
113
+ }
114
+ }
115
+ async function checkRegistryUpdate(name, entry) {
116
+ try {
117
+ // Get craft info from registry
118
+ const craftInfo = await registry_client_1.registryClient.getCraftInfo(name);
119
+ if (!craftInfo) {
120
+ logger_1.logger.debug(`Could not fetch registry info for ${name}`);
121
+ return {
122
+ name,
123
+ current: entry.version,
124
+ wanted: entry.version,
125
+ latest: 'unknown',
126
+ type: entry.type,
127
+ source: 'registry',
128
+ hasUpdate: false
129
+ };
130
+ }
131
+ const latestVersion = craftInfo.version || 'unknown';
132
+ const currentVersion = entry.version;
133
+ // Compare versions
134
+ const hasUpdate = latestVersion !== 'unknown' && latestVersion !== currentVersion;
135
+ return {
136
+ name,
137
+ current: currentVersion,
138
+ wanted: latestVersion, // For now, wanted = latest (semver resolution would be more complex)
139
+ latest: latestVersion,
140
+ type: entry.type,
141
+ source: 'registry',
142
+ hasUpdate,
143
+ updateType: hasUpdate ? (0, version_utils_1.getUpdateType)(currentVersion, latestVersion) : undefined
144
+ };
145
+ }
146
+ catch (error) {
147
+ const message = error instanceof Error ? error.message : String(error);
148
+ logger_1.logger.debug(`Registry check failed for ${name}: ${message}`);
149
+ return null;
150
+ }
151
+ }
152
+ async function checkGitUpdate(name, entry) {
153
+ if (!entry.git)
154
+ return null;
155
+ try {
156
+ const gitUrl = entry.git;
157
+ const currentCommit = entry.commit || entry.integrity;
158
+ const currentTag = entry.tag;
159
+ const currentBranch = entry.branch || 'main';
160
+ let _latestRef = '';
161
+ let latestDisplay = '';
162
+ let hasUpdate = false;
163
+ if (currentTag) {
164
+ // Check for newer tags
165
+ const tags = getRemoteTags(gitUrl);
166
+ if (tags.length > 0) {
167
+ // Sort tags by semver if possible, otherwise alphabetically
168
+ const sortedTags = (0, version_utils_1.sortTagsBySemver)(tags);
169
+ latestDisplay = sortedTags[0] || currentTag;
170
+ hasUpdate = latestDisplay !== currentTag && (0, version_utils_1.isNewerVersion)(currentTag, latestDisplay);
171
+ }
172
+ else {
173
+ latestDisplay = currentTag;
174
+ }
175
+ }
176
+ else {
177
+ // Check for newer commits on branch
178
+ const latestCommit = getRemoteHeadCommit(gitUrl, currentBranch);
179
+ if (latestCommit && currentCommit) {
180
+ const shortCurrent = currentCommit.substring(0, 7);
181
+ const shortLatest = latestCommit.substring(0, 7);
182
+ latestDisplay = shortLatest;
183
+ hasUpdate = shortCurrent !== shortLatest && latestCommit !== currentCommit;
184
+ }
185
+ else {
186
+ latestDisplay = currentCommit?.substring(0, 7) || 'unknown';
187
+ }
188
+ }
189
+ const currentDisplay = currentTag || currentCommit?.substring(0, 7) || 'unknown';
190
+ return {
191
+ name,
192
+ current: currentDisplay,
193
+ wanted: latestDisplay,
194
+ latest: latestDisplay,
195
+ type: entry.type,
196
+ source: 'git',
197
+ hasUpdate,
198
+ updateType: hasUpdate ? 'commit' : undefined
199
+ };
200
+ }
201
+ catch (error) {
202
+ const message = error instanceof Error ? error.message : String(error);
203
+ logger_1.logger.debug(`Git check failed for ${name}: ${message}`);
204
+ return {
205
+ name,
206
+ current: entry.tag || entry.commit?.substring(0, 7) || entry.version,
207
+ wanted: 'unknown',
208
+ latest: 'unknown',
209
+ type: entry.type,
210
+ source: 'git',
211
+ hasUpdate: false
212
+ };
213
+ }
214
+ }
215
+ function getRemoteTags(gitUrl) {
216
+ try {
217
+ const output = (0, child_process_1.execSync)(`git ls-remote --tags ${gitUrl} 2>/dev/null`, {
218
+ encoding: 'utf8',
219
+ timeout: 15000
220
+ });
221
+ const tags = [];
222
+ const lines = output.split('\n');
223
+ for (const line of lines) {
224
+ // Extract tag name from refs/tags/tagname
225
+ const match = line.match(/refs\/tags\/([^^]+)$/);
226
+ if (match && match[1]) {
227
+ tags.push(match[1]);
228
+ }
229
+ }
230
+ return tags;
231
+ }
232
+ catch {
233
+ return [];
234
+ }
235
+ }
236
+ function getRemoteHeadCommit(gitUrl, branch) {
237
+ try {
238
+ const output = (0, child_process_1.execSync)(`git ls-remote ${gitUrl} refs/heads/${branch} 2>/dev/null`, {
239
+ encoding: 'utf8',
240
+ timeout: 15000
241
+ });
242
+ const match = output.match(/^([a-f0-9]+)/);
243
+ return match ? match[1] : null;
244
+ }
245
+ catch {
246
+ return null;
247
+ }
248
+ }
249
+ /**
250
+ * Exported wrapper for testing - fetches remote git tags from a repository.
251
+ *
252
+ * @param gitUrl - The git repository URL
253
+ * @returns Array of tag names found in the repository
254
+ */
255
+ function getRemoteTagsExported(gitUrl) {
256
+ return getRemoteTags(gitUrl);
257
+ }
258
+ /**
259
+ * Exported wrapper for testing - fetches the latest commit hash from a git branch.
260
+ *
261
+ * @param gitUrl - The git repository URL
262
+ * @param branch - The branch name to check
263
+ * @returns The commit hash or null if not found
264
+ */
265
+ function getRemoteHeadCommitExported(gitUrl, branch) {
266
+ return getRemoteHeadCommit(gitUrl, branch);
267
+ }
268
+ //# sourceMappingURL=outdated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outdated.js","sourceRoot":"","sources":["../../src/commands/outdated.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Creates the publish command for publishing a craft to the registry.
4
+ *
5
+ * @returns The configured Commander command instance
6
+ */
7
+ export declare function createPublishCommand(): Command;
8
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAU9C"}
@@ -0,0 +1,198 @@
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.createPublishCommand = createPublishCommand;
7
+ const commander_1 = require("commander");
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const file_system_1 = require("../utils/file-system");
11
+ const logger_1 = require("../utils/logger");
12
+ const registry_client_1 = require("../services/registry-client");
13
+ const config_manager_1 = require("../services/config-manager");
14
+ /**
15
+ * Creates the publish command for publishing a craft to the registry.
16
+ *
17
+ * @returns The configured Commander command instance
18
+ */
19
+ function createPublishCommand() {
20
+ return new commander_1.Command('publish')
21
+ .description('Publish a craft to the registry')
22
+ .argument('[path]', 'Path to craft directory', '.')
23
+ .option('--access <level>', 'Access level: public, private, organization', 'public')
24
+ .option('--tag <tag>', 'Publish with dist-tag (e.g., beta, latest)')
25
+ .option('--dry-run', 'Validate without publishing')
26
+ .action(async (craftPath, options) => {
27
+ await publishCommand(craftPath, options);
28
+ });
29
+ }
30
+ async function publishCommand(craftPath, options) {
31
+ try {
32
+ // 1. Resolve path
33
+ const fullPath = path_1.default.resolve(craftPath);
34
+ if (!await fs_extra_1.default.pathExists(fullPath)) {
35
+ logger_1.logger.error(`Directory not found: ${fullPath}`);
36
+ process.exit(1);
37
+ }
38
+ // 2. Read craftdesk.json from target directory
39
+ const craftJson = await (0, file_system_1.readCraftDeskJson)(fullPath);
40
+ if (!craftJson) {
41
+ logger_1.logger.error('No craftdesk.json found in target directory');
42
+ logger_1.logger.info('Create a craftdesk.json file or run "craftdesk init" first.');
43
+ process.exit(1);
44
+ }
45
+ // 3. Validate required fields
46
+ const validation = validateCraftJson(craftJson);
47
+ if (!validation.valid) {
48
+ logger_1.logger.error('Invalid craftdesk.json:');
49
+ validation.errors.forEach(err => logger_1.logger.error(` - ${err}`));
50
+ process.exit(1);
51
+ }
52
+ // 4. Collect files first (needed for dry-run)
53
+ const files = await collectCraftFiles(fullPath, craftJson);
54
+ if (files.length === 0) {
55
+ logger_1.logger.error('No files to publish.');
56
+ process.exit(1);
57
+ }
58
+ // 5. Display preview
59
+ logger_1.logger.info(`\nPublishing ${craftJson.author}/${craftJson.name}@${craftJson.version}\n`);
60
+ logger_1.logger.info('Files to publish:');
61
+ files.forEach(f => logger_1.logger.info(` ${f.path}`));
62
+ logger_1.logger.info(`\nTotal: ${files.length} file(s)`);
63
+ // 6. If dry-run, stop here (before auth check)
64
+ if (options.dryRun) {
65
+ logger_1.logger.success('\nDry run complete. No changes made.');
66
+ logger_1.logger.info('Run without --dry-run to publish.');
67
+ return;
68
+ }
69
+ // 7. Check registry and authentication (only for actual publish)
70
+ const registryUrl = await config_manager_1.configManager.getDefaultRegistry();
71
+ if (!registryUrl) {
72
+ logger_1.logger.error('No registry configured.');
73
+ logger_1.logger.info('Add a registry to your craftdesk.json:');
74
+ logger_1.logger.info(' "registries": { "default": { "url": "https://your-registry.com" } }');
75
+ process.exit(1);
76
+ }
77
+ const token = await config_manager_1.configManager.getAuthToken(registryUrl);
78
+ if (!token) {
79
+ logger_1.logger.error('Not authenticated.');
80
+ logger_1.logger.info('Run "craftdesk login" first to authenticate with the registry.');
81
+ process.exit(1);
82
+ }
83
+ // 8. Upload version
84
+ logger_1.logger.startSpinner('Publishing...');
85
+ const result = await registry_client_1.registryClient.createVersion(craftJson.author, craftJson.name, {
86
+ version: craftJson.version,
87
+ type: craftJson.type || 'skill',
88
+ description: craftJson.description,
89
+ main_file: detectMainFile(craftJson),
90
+ files: files
91
+ });
92
+ // 9. Set visibility if public
93
+ if (options.access === 'public') {
94
+ await registry_client_1.registryClient.publishCraft(craftJson.author, craftJson.name, { visibility: 'public' });
95
+ }
96
+ logger_1.logger.succeedSpinner(`Published ${craftJson.name}@${craftJson.version}`);
97
+ // 9. Display success
98
+ console.log('');
99
+ logger_1.logger.success('Publication successful!');
100
+ logger_1.logger.info(`\nView at: ${registryUrl}/crafts/${craftJson.author}/${craftJson.name}`);
101
+ if (result.download_url) {
102
+ logger_1.logger.info(`Download: ${registryUrl}${result.download_url}`);
103
+ }
104
+ }
105
+ catch (error) {
106
+ logger_1.logger.failSpinner('Publication failed');
107
+ const message = error instanceof Error ? error.message : String(error);
108
+ logger_1.logger.error(message);
109
+ process.exit(1);
110
+ }
111
+ }
112
+ function validateCraftJson(craftJson) {
113
+ const errors = [];
114
+ if (!craftJson.name) {
115
+ errors.push('Missing required field: name');
116
+ }
117
+ if (!craftJson.version) {
118
+ errors.push('Missing required field: version');
119
+ }
120
+ else if (!/^\d+\.\d+\.\d+(\.\d+)?$/.test(craftJson.version)) {
121
+ errors.push('Version must be in semver format (e.g., 1.0.0)');
122
+ }
123
+ if (!craftJson.author) {
124
+ errors.push('Missing required field: author');
125
+ }
126
+ if (craftJson.type && !['skill', 'agent', 'command', 'hook', 'plugin'].includes(craftJson.type)) {
127
+ errors.push('Invalid type. Must be: skill, agent, command, hook, or plugin');
128
+ }
129
+ return {
130
+ valid: errors.length === 0,
131
+ errors
132
+ };
133
+ }
134
+ async function collectCraftFiles(craftPath, _craftJson) {
135
+ const files = [];
136
+ // File extensions to include
137
+ const includeExtensions = [
138
+ '.md', '.ts', '.js', '.json', '.yaml', '.yml', '.sh', '.py', '.rb'
139
+ ];
140
+ // Directories to exclude
141
+ const excludeDirs = ['node_modules', '.git', 'dist', 'coverage'];
142
+ // Files/patterns to exclude
143
+ const excludeFiles = ['.lock', '.env', '.DS_Store'];
144
+ async function walkDir(dir, basePath = '') {
145
+ const entries = await fs_extra_1.default.readdir(dir, { withFileTypes: true });
146
+ for (const entry of entries) {
147
+ const fullPath = path_1.default.join(dir, entry.name);
148
+ const relativePath = basePath ? path_1.default.join(basePath, entry.name) : entry.name;
149
+ if (entry.isDirectory()) {
150
+ // Skip excluded directories
151
+ if (excludeDirs.includes(entry.name)) {
152
+ continue;
153
+ }
154
+ await walkDir(fullPath, relativePath);
155
+ }
156
+ else if (entry.isFile()) {
157
+ // Check if file should be excluded
158
+ const shouldExclude = excludeFiles.some(pattern => entry.name.includes(pattern));
159
+ if (shouldExclude)
160
+ continue;
161
+ // Check if file extension is included
162
+ const ext = path_1.default.extname(entry.name);
163
+ if (!includeExtensions.includes(ext))
164
+ continue;
165
+ try {
166
+ const content = await fs_extra_1.default.readFile(fullPath, 'utf-8');
167
+ files.push({
168
+ path: relativePath,
169
+ content
170
+ });
171
+ }
172
+ catch (_error) {
173
+ logger_1.logger.warn(`Could not read file: ${relativePath}`);
174
+ }
175
+ }
176
+ }
177
+ }
178
+ await walkDir(craftPath);
179
+ return files;
180
+ }
181
+ function detectMainFile(craftJson) {
182
+ const type = craftJson.type || 'skill';
183
+ switch (type) {
184
+ case 'skill':
185
+ return 'SKILL.md';
186
+ case 'agent':
187
+ return 'AGENT.md';
188
+ case 'command':
189
+ return 'command.ts';
190
+ case 'hook':
191
+ return 'hook.ts';
192
+ case 'plugin':
193
+ return 'plugin.json';
194
+ default:
195
+ return 'README.md';
196
+ }
197
+ }
198
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,8 @@
1
1
  import { Command } from 'commander';
2
+ /**
3
+ * Creates the remove command for removing a craft dependency from the project.
4
+ *
5
+ * @returns The configured Commander command instance
6
+ */
2
7
  export declare function createRemoveCommand(): Command;
3
8
  //# sourceMappingURL=remove.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C"}
1
+ {"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C"}
@@ -5,15 +5,21 @@ const commander_1 = require("commander");
5
5
  const file_system_1 = require("../utils/file-system");
6
6
  const logger_1 = require("../utils/logger");
7
7
  const installer_1 = require("../services/installer");
8
+ /**
9
+ * Creates the remove command for removing a craft dependency from the project.
10
+ *
11
+ * @returns The configured Commander command instance
12
+ */
8
13
  function createRemoveCommand() {
9
14
  return new commander_1.Command('remove')
10
15
  .description('Remove a dependency')
11
16
  .argument('<craft>', 'Craft name to remove')
12
- .action(async (craftName) => {
13
- await removeCommand(craftName);
17
+ .option('-f, --force', 'Force removal even if other crafts depend on it')
18
+ .action(async (craftName, options) => {
19
+ await removeCommand(craftName, options);
14
20
  });
15
21
  }
16
- async function removeCommand(craftName) {
22
+ async function removeCommand(craftName, options = {}) {
17
23
  try {
18
24
  // Read craftdesk.json
19
25
  const craftDeskJson = await (0, file_system_1.readCraftDeskJson)();
@@ -21,17 +27,38 @@ async function removeCommand(craftName) {
21
27
  logger_1.logger.error('No craftdesk.json found in current directory');
22
28
  process.exit(1);
23
29
  }
30
+ // Read lockfile to check for dependencies
31
+ const lockfile = await (0, file_system_1.readCraftDeskLock)();
32
+ // Check if other plugins depend on this craft
33
+ if (lockfile?.pluginTree && !options.force) {
34
+ const dependents = [];
35
+ for (const [pluginName, pluginInfo] of Object.entries(lockfile.pluginTree)) {
36
+ if (pluginInfo.dependencies?.includes(craftName)) {
37
+ dependents.push(`${pluginName}@${pluginInfo.version}`);
38
+ }
39
+ }
40
+ if (dependents.length > 0) {
41
+ logger_1.logger.warn(`Warning: ${craftName} is required by:`);
42
+ for (const dep of dependents) {
43
+ logger_1.logger.warn(` - ${dep}`);
44
+ }
45
+ logger_1.logger.log('');
46
+ logger_1.logger.info('Use --force to remove anyway');
47
+ process.exit(1);
48
+ }
49
+ }
24
50
  // Check if craft exists in any dependency field
25
51
  let found = false;
26
52
  let foundInField = null;
27
53
  const depFields = ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'];
28
54
  for (const field of depFields) {
29
- if (craftDeskJson[field] && craftDeskJson[field][craftName]) {
55
+ const deps = craftDeskJson[field];
56
+ if (deps && deps[craftName]) {
30
57
  found = true;
31
58
  foundInField = field;
32
- delete craftDeskJson[field][craftName];
59
+ delete deps[craftName];
33
60
  // Remove empty objects
34
- if (Object.keys(craftDeskJson[field]).length === 0) {
61
+ if (Object.keys(deps).length === 0) {
35
62
  delete craftDeskJson[field];
36
63
  }
37
64
  break;
@@ -44,15 +71,28 @@ async function removeCommand(craftName) {
44
71
  // Save updated craftdesk.json
45
72
  await (0, file_system_1.writeCraftDeskJson)(craftDeskJson);
46
73
  logger_1.logger.success(`Removed ${craftName} from ${foundInField}`);
47
- // Read lockfile to get craft type
48
- const lockfile = await (0, file_system_1.readCraftDeskLock)();
74
+ // Update lockfile if it exists
49
75
  if (lockfile && lockfile.crafts[craftName]) {
50
76
  const craftEntry = lockfile.crafts[craftName];
51
77
  // Remove from file system
52
78
  await installer_1.installer.removeCraft(craftName, craftEntry.type);
53
79
  // Remove from lockfile
54
80
  delete lockfile.crafts[craftName];
55
- // TODO: Clean up dependency tree in lockfile
81
+ // Clean up plugin tree in lockfile
82
+ if (lockfile.pluginTree && lockfile.pluginTree[craftName]) {
83
+ delete lockfile.pluginTree[craftName];
84
+ }
85
+ // Update requiredBy for other plugins
86
+ if (lockfile.pluginTree) {
87
+ for (const [_pluginName, pluginInfo] of Object.entries(lockfile.pluginTree)) {
88
+ if (pluginInfo.requiredBy) {
89
+ pluginInfo.requiredBy = pluginInfo.requiredBy.filter(dep => dep !== craftName);
90
+ }
91
+ if (pluginInfo.dependencies) {
92
+ pluginInfo.dependencies = pluginInfo.dependencies.filter(dep => dep !== craftName);
93
+ }
94
+ }
95
+ }
56
96
  // Save updated lockfile
57
97
  await (0, file_system_1.writeCraftDeskLock)(lockfile);
58
98
  logger_1.logger.success('Updated craftdesk.lock');
@@ -67,7 +107,8 @@ async function removeCommand(craftName) {
67
107
  logger_1.logger.success('Craft removed successfully!');
68
108
  }
69
109
  catch (error) {
70
- logger_1.logger.error(`Failed to remove craft: ${error.message}`);
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ logger_1.logger.error(`Failed to remove craft: ${message}`);
71
112
  process.exit(1);
72
113
  }
73
114
  }