craftdesk 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/.claude/settings.local.json +19 -0
  2. package/.github/workflows/ci.yml +94 -0
  3. package/API.md +414 -0
  4. package/README.md +778 -0
  5. package/TESTING.md +263 -0
  6. package/bin/craftdesk.js +4 -0
  7. package/dist/commands/add.d.ts +3 -0
  8. package/dist/commands/add.d.ts.map +1 -0
  9. package/dist/commands/add.js +284 -0
  10. package/dist/commands/add.js.map +1 -0
  11. package/dist/commands/config.d.ts +3 -0
  12. package/dist/commands/config.d.ts.map +1 -0
  13. package/dist/commands/config.js +56 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/init.d.ts +3 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +57 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/install.d.ts +3 -0
  20. package/dist/commands/install.d.ts.map +1 -0
  21. package/dist/commands/install.js +109 -0
  22. package/dist/commands/install.js.map +1 -0
  23. package/dist/commands/list.d.ts +3 -0
  24. package/dist/commands/list.d.ts.map +1 -0
  25. package/dist/commands/list.js +117 -0
  26. package/dist/commands/list.js.map +1 -0
  27. package/dist/commands/remove.d.ts +3 -0
  28. package/dist/commands/remove.d.ts.map +1 -0
  29. package/dist/commands/remove.js +74 -0
  30. package/dist/commands/remove.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +51 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/services/config-manager.d.ts +88 -0
  36. package/dist/services/config-manager.d.ts.map +1 -0
  37. package/dist/services/config-manager.js +143 -0
  38. package/dist/services/config-manager.js.map +1 -0
  39. package/dist/services/git-resolver.d.ts +139 -0
  40. package/dist/services/git-resolver.d.ts.map +1 -0
  41. package/dist/services/git-resolver.js +340 -0
  42. package/dist/services/git-resolver.js.map +1 -0
  43. package/dist/services/installer.d.ts +98 -0
  44. package/dist/services/installer.d.ts.map +1 -0
  45. package/dist/services/installer.js +274 -0
  46. package/dist/services/installer.js.map +1 -0
  47. package/dist/services/registry-client.d.ts +27 -0
  48. package/dist/services/registry-client.d.ts.map +1 -0
  49. package/dist/services/registry-client.js +134 -0
  50. package/dist/services/registry-client.js.map +1 -0
  51. package/dist/types/config.d.ts +17 -0
  52. package/dist/types/config.d.ts.map +1 -0
  53. package/dist/types/config.js +3 -0
  54. package/dist/types/config.js.map +1 -0
  55. package/dist/types/craftdesk-json.d.ts +42 -0
  56. package/dist/types/craftdesk-json.d.ts.map +1 -0
  57. package/dist/types/craftdesk-json.js +3 -0
  58. package/dist/types/craftdesk-json.js.map +1 -0
  59. package/dist/types/craftdesk-lock.d.ts +34 -0
  60. package/dist/types/craftdesk-lock.d.ts.map +1 -0
  61. package/dist/types/craftdesk-lock.js +3 -0
  62. package/dist/types/craftdesk-lock.js.map +1 -0
  63. package/dist/utils/file-system.d.ts +10 -0
  64. package/dist/utils/file-system.d.ts.map +1 -0
  65. package/dist/utils/file-system.js +60 -0
  66. package/dist/utils/file-system.js.map +1 -0
  67. package/dist/utils/logger.d.ts +18 -0
  68. package/dist/utils/logger.d.ts.map +1 -0
  69. package/dist/utils/logger.js +72 -0
  70. package/dist/utils/logger.js.map +1 -0
  71. package/docs/DEPENDENCY_RESOLUTION.md +237 -0
  72. package/examples/craftdesk-all-sources.json +79 -0
  73. package/examples/craftdesk-git-monorepo.json +41 -0
  74. package/examples/craftdesk-multi-registry.json +40 -0
  75. package/examples/craftdesk-with-registries.json +49 -0
  76. package/examples/simple-craftdesk.json +10 -0
  77. package/package.json +32 -25
  78. package/src/commands/add.ts +314 -0
  79. package/src/commands/init.ts +55 -0
  80. package/src/commands/install.ts +126 -0
  81. package/src/commands/list.ts +126 -0
  82. package/src/commands/remove.ts +82 -0
  83. package/src/index.ts +56 -0
  84. package/src/services/config-manager.ts +150 -0
  85. package/src/services/git-resolver.ts +373 -0
  86. package/src/services/installer.ts +314 -0
  87. package/src/services/registry-client.ts +163 -0
  88. package/src/types/craftdesk-json.ts +53 -0
  89. package/src/types/craftdesk-lock.ts +38 -0
  90. package/src/utils/file-system.ts +55 -0
  91. package/src/utils/logger.ts +82 -0
  92. package/tests/fixtures/craftdesk-git.json +17 -0
  93. package/tests/fixtures/craftdesk.json +15 -0
  94. package/tests/helpers/test-utils.ts +60 -0
  95. package/tests/integration/init-command.test.ts +70 -0
  96. package/tests/integration/list-command.test.ts +77 -0
  97. package/tests/unit/config-manager.test.ts +228 -0
  98. package/tests/unit/git-resolver.test.ts +303 -0
  99. package/tests/unit/installer.test.ts +105 -0
  100. package/tsconfig.json +20 -0
  101. package/vitest.config.ts +29 -0
  102. package/LICENSE +0 -21
  103. package/index.js +0 -4
@@ -0,0 +1,57 @@
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.createInitCommand = createInitCommand;
7
+ const commander_1 = require("commander");
8
+ const path_1 = __importDefault(require("path"));
9
+ const file_system_1 = require("../utils/file-system");
10
+ const logger_1 = require("../utils/logger");
11
+ function createInitCommand() {
12
+ return new commander_1.Command('init')
13
+ .description('Initialize a new craftdesk.json file')
14
+ .option('-y, --yes', 'Skip prompts and use defaults')
15
+ .option('-n, --name <name>', 'Project name')
16
+ .option('--project-version <version>', 'Project version', '1.0.0')
17
+ .option('-t, --type <type>', 'Project type (skill, agent, command, hook, plugin)', 'skill')
18
+ .option('-d, --description <desc>', 'Project description')
19
+ .option('-a, --author <author>', 'Author name')
20
+ .option('-l, --license <license>', 'License', 'MIT')
21
+ .action(async (options) => {
22
+ await initCommand(options);
23
+ });
24
+ }
25
+ async function initCommand(options) {
26
+ try {
27
+ // Check if craftdesk.json already exists
28
+ if (await (0, file_system_1.exists)('craftdesk.json')) {
29
+ logger_1.logger.error('craftdesk.json already exists in this directory');
30
+ process.exit(1);
31
+ }
32
+ const config = {
33
+ name: options.name || path_1.default.basename(process.cwd()),
34
+ version: options.projectVersion,
35
+ type: options.type,
36
+ description: options.description || undefined,
37
+ author: options.author || undefined,
38
+ license: options.license || undefined,
39
+ dependencies: {},
40
+ registries: {
41
+ default: {
42
+ url: 'https://craftdesk.ai'
43
+ }
44
+ }
45
+ };
46
+ // Write craftdesk.json
47
+ await (0, file_system_1.writeCraftDeskJson)(config);
48
+ logger_1.logger.success('Created craftdesk.json');
49
+ logger_1.logger.info('Run "craftdesk install" to install dependencies');
50
+ logger_1.logger.info('Run "craftdesk add <craft>" to add dependencies');
51
+ }
52
+ catch (error) {
53
+ logger_1.logger.error(`Failed to initialize: ${error.message}`);
54
+ process.exit(1);
55
+ }
56
+ }
57
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";;;;;AAMA,8CAaC;AAnBD,yCAAoC;AACpC,gDAAwB;AAExB,sDAAkE;AAClE,4CAAyC;AAEzC,SAAgB,iBAAiB;IAC/B,OAAO,IAAI,mBAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,WAAW,EAAE,+BAA+B,CAAC;SACpD,MAAM,CAAC,mBAAmB,EAAE,cAAc,CAAC;SAC3C,MAAM,CAAC,6BAA6B,EAAE,iBAAiB,EAAE,OAAO,CAAC;SACjE,MAAM,CAAC,mBAAmB,EAAE,oDAAoD,EAAE,OAAO,CAAC;SAC1F,MAAM,CAAC,0BAA0B,EAAE,qBAAqB,CAAC;SACzD,MAAM,CAAC,uBAAuB,EAAE,aAAa,CAAC;SAC9C,MAAM,CAAC,yBAAyB,EAAE,SAAS,EAAE,KAAK,CAAC;SACnD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAY;IACrC,IAAI,CAAC;QACH,yCAAyC;QACzC,IAAI,MAAM,IAAA,oBAAM,EAAC,gBAAgB,CAAC,EAAE,CAAC;YACnC,eAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAkB;YAC5B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,cAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAClD,OAAO,EAAE,OAAO,CAAC,cAAc;YAC/B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS;YAC7C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS;YACnC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,SAAS;YACrC,YAAY,EAAE,EAAE;YAChB,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,GAAG,EAAE,sBAAsB;iBAC5B;aACF;SACF,CAAC;QAEF,uBAAuB;QACvB,MAAM,IAAA,gCAAkB,EAAC,MAAM,CAAC,CAAC;QAEjC,eAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QACzC,eAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QAC/D,eAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,eAAM,CAAC,KAAK,CAAC,yBAAyB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createInstallCommand(): Command;
3
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,oBAAoB,IAAI,OAAO,CAQ9C"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createInstallCommand = createInstallCommand;
4
+ const commander_1 = require("commander");
5
+ const file_system_1 = require("../utils/file-system");
6
+ const logger_1 = require("../utils/logger");
7
+ const registry_client_1 = require("../services/registry-client");
8
+ const git_resolver_1 = require("../services/git-resolver");
9
+ const installer_1 = require("../services/installer");
10
+ function createInstallCommand() {
11
+ return new commander_1.Command('install')
12
+ .description('Install all dependencies from craftdesk.json')
13
+ .option('--no-lockfile', 'Ignore craftdesk.lock and re-resolve dependencies')
14
+ .option('--production', 'Skip devDependencies')
15
+ .action(async (options) => {
16
+ await installCommand(options);
17
+ });
18
+ }
19
+ async function installCommand(options) {
20
+ try {
21
+ // Read craftdesk.json
22
+ const craftDeskJson = await (0, file_system_1.readCraftDeskJson)();
23
+ if (!craftDeskJson) {
24
+ logger_1.logger.error('No craftdesk.json found in current directory');
25
+ logger_1.logger.info('Run "craftdesk init" to create one');
26
+ process.exit(1);
27
+ }
28
+ logger_1.logger.info('Installing dependencies from craftdesk.json...');
29
+ let lockfile = null;
30
+ // Check for existing lockfile
31
+ if (!options.noLockfile) {
32
+ lockfile = await (0, file_system_1.readCraftDeskLock)();
33
+ }
34
+ if (lockfile) {
35
+ // Install from lockfile
36
+ logger_1.logger.info('Installing from craftdesk.lock...');
37
+ logger_1.logger.startSpinner('Installing crafts...');
38
+ await installer_1.installer.installFromLockfile(lockfile);
39
+ logger_1.logger.success('Installation complete!');
40
+ }
41
+ else {
42
+ // Resolve dependencies
43
+ logger_1.logger.info('No lockfile found. Resolving dependencies...');
44
+ logger_1.logger.startSpinner('Resolving dependencies...');
45
+ const rawDependencies = craftDeskJson.dependencies || {};
46
+ if (Object.keys(rawDependencies).length === 0) {
47
+ logger_1.logger.stopSpinner();
48
+ logger_1.logger.info('No dependencies to install');
49
+ return;
50
+ }
51
+ // Collect all dependencies (including devDependencies if not --production)
52
+ const allDependencies = { ...rawDependencies };
53
+ if (!options.production && craftDeskJson.devDependencies) {
54
+ Object.assign(allDependencies, craftDeskJson.devDependencies);
55
+ }
56
+ // Use git resolver which handles both git AND registry dependencies
57
+ const resolution = await git_resolver_1.gitResolver.resolveAllDependencies(allDependencies);
58
+ if (!resolution) {
59
+ logger_1.logger.failSpinner('Failed to resolve dependencies');
60
+ process.exit(1);
61
+ }
62
+ logger_1.logger.succeedSpinner('Dependencies resolved');
63
+ // For registry dependencies that need resolution, fetch their info
64
+ logger_1.logger.startSpinner('Fetching registry crafts...');
65
+ for (const [name, entry] of Object.entries(resolution.resolved)) {
66
+ if (entry.needsResolution) {
67
+ const craftInfo = await registry_client_1.registryClient.getCraftInfo(name, entry.version, entry.registry);
68
+ if (craftInfo) {
69
+ resolution.resolved[name] = {
70
+ version: craftInfo.version,
71
+ resolved: craftInfo.download_url || `http://localhost:3000/api/v1/crafts/${craftInfo.author}/${craftInfo.name}/versions/${craftInfo.version}/download`,
72
+ integrity: craftInfo.integrity || 'sha256-placeholder',
73
+ type: craftInfo.type,
74
+ author: craftInfo.author,
75
+ dependencies: craftInfo.dependencies || {}
76
+ };
77
+ }
78
+ else {
79
+ logger_1.logger.failSpinner(`Failed to resolve craft: ${name}`);
80
+ process.exit(1);
81
+ }
82
+ }
83
+ }
84
+ logger_1.logger.succeedSpinner('Registry crafts fetched');
85
+ // Install resolved crafts
86
+ logger_1.logger.startSpinner('Installing crafts...');
87
+ const newLockfile = resolution.lockfile;
88
+ await installer_1.installer.installFromLockfile(newLockfile);
89
+ // Save lockfile
90
+ await (0, file_system_1.writeCraftDeskLock)(newLockfile);
91
+ logger_1.logger.success('Created craftdesk.lock');
92
+ logger_1.logger.success('Installation complete!');
93
+ }
94
+ // Show summary
95
+ const installedCrafts = await installer_1.installer.listInstalled();
96
+ if (installedCrafts.length > 0) {
97
+ logger_1.logger.log('\nInstalled crafts:');
98
+ for (const craft of installedCrafts) {
99
+ logger_1.logger.log(` • ${craft.name}@${craft.version} (${craft.type})`);
100
+ }
101
+ }
102
+ }
103
+ catch (error) {
104
+ logger_1.logger.failSpinner();
105
+ logger_1.logger.error(`Installation failed: ${error.message}`);
106
+ process.exit(1);
107
+ }
108
+ }
109
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createListCommand(): Command;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,iBAAiB,IAAI,OAAO,CAS3C"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createListCommand = createListCommand;
4
+ const commander_1 = require("commander");
5
+ const file_system_1 = require("../utils/file-system");
6
+ const logger_1 = require("../utils/logger");
7
+ const installer_1 = require("../services/installer");
8
+ function createListCommand() {
9
+ return new commander_1.Command('list')
10
+ .description('List installed crafts')
11
+ .option('--tree', 'Show dependency tree')
12
+ .option('--depth <n>', 'Limit tree depth', parseInt)
13
+ .option('--json', 'Output as JSON')
14
+ .action(async (options) => {
15
+ await listCommand(options);
16
+ });
17
+ }
18
+ async function listCommand(options) {
19
+ try {
20
+ // Read craftdesk.json for project info
21
+ const craftDeskJson = await (0, file_system_1.readCraftDeskJson)();
22
+ if (!craftDeskJson) {
23
+ logger_1.logger.error('No craftdesk.json found in current directory');
24
+ process.exit(1);
25
+ }
26
+ // Get installed crafts
27
+ const installedCrafts = await installer_1.installer.listInstalled();
28
+ if (options.json) {
29
+ // JSON output
30
+ console.log(JSON.stringify({
31
+ name: craftDeskJson.name,
32
+ version: craftDeskJson.version,
33
+ installedCrafts
34
+ }, null, 2));
35
+ return;
36
+ }
37
+ // Display project info
38
+ logger_1.logger.log(`${craftDeskJson.name}@${craftDeskJson.version}`);
39
+ if (installedCrafts.length === 0) {
40
+ logger_1.logger.info('No crafts installed');
41
+ logger_1.logger.info('Run "craftdesk install" to install dependencies');
42
+ return;
43
+ }
44
+ if (options.tree) {
45
+ // Show dependency tree
46
+ const lockfile = await (0, file_system_1.readCraftDeskLock)();
47
+ if (!lockfile) {
48
+ logger_1.logger.warn('No craftdesk.lock found. Cannot show dependency tree.');
49
+ logger_1.logger.info('Run "craftdesk install" to generate lockfile');
50
+ }
51
+ else {
52
+ displayDependencyTree(lockfile, options.depth);
53
+ }
54
+ }
55
+ else {
56
+ // Simple list
57
+ logger_1.logger.log('\nInstalled crafts:');
58
+ for (const craft of installedCrafts) {
59
+ const typeIcon = getTypeIcon(craft.type);
60
+ logger_1.logger.log(` ${typeIcon} ${craft.name}@${craft.version} (${craft.type})`);
61
+ }
62
+ logger_1.logger.log('');
63
+ logger_1.logger.info(`Total: ${installedCrafts.length} crafts installed`);
64
+ }
65
+ }
66
+ catch (error) {
67
+ logger_1.logger.error(`Failed to list crafts: ${error.message}`);
68
+ process.exit(1);
69
+ }
70
+ }
71
+ function getTypeIcon(type) {
72
+ switch (type) {
73
+ case 'skill':
74
+ return '📚';
75
+ case 'agent':
76
+ return '🤖';
77
+ case 'command':
78
+ return '⚡';
79
+ case 'hook':
80
+ return '🔗';
81
+ default:
82
+ return '📦';
83
+ }
84
+ }
85
+ function displayDependencyTree(lockfile, maxDepth) {
86
+ logger_1.logger.log('\nDependency tree:');
87
+ if (!lockfile.tree) {
88
+ logger_1.logger.warn('No dependency tree information in lockfile');
89
+ return;
90
+ }
91
+ const tree = lockfile.tree;
92
+ const depth = 0;
93
+ const prefix = '';
94
+ for (const [key, value] of Object.entries(tree)) {
95
+ displayTreeNode(key, value, depth, maxDepth || Infinity, prefix, Object.keys(tree).indexOf(key) === Object.keys(tree).length - 1);
96
+ }
97
+ }
98
+ function displayTreeNode(key, node, depth, maxDepth, prefix, isLast) {
99
+ if (depth > maxDepth)
100
+ return;
101
+ const connector = isLast ? '└── ' : '├── ';
102
+ const [name, version] = key.split('@');
103
+ logger_1.logger.log(`${prefix}${connector}${name}@${version}`);
104
+ if (typeof node === 'object' && node.dependencies && depth < maxDepth) {
105
+ const newPrefix = prefix + (isLast ? ' ' : '│ ');
106
+ const deps = Object.entries(node.dependencies);
107
+ deps.forEach(([depKey, depValue], index) => {
108
+ const isLastDep = index === deps.length - 1;
109
+ displayTreeNode(depKey, depValue, depth + 1, maxDepth, newPrefix, isLastDep);
110
+ });
111
+ }
112
+ else if (typeof node === 'string' && node === '(shared)') {
113
+ // Shared dependency indicator
114
+ logger_1.logger.log(' (shared)');
115
+ }
116
+ }
117
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createRemoveCommand(): Command;
3
+ //# sourceMappingURL=remove.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRemoveCommand = createRemoveCommand;
4
+ const commander_1 = require("commander");
5
+ const file_system_1 = require("../utils/file-system");
6
+ const logger_1 = require("../utils/logger");
7
+ const installer_1 = require("../services/installer");
8
+ function createRemoveCommand() {
9
+ return new commander_1.Command('remove')
10
+ .description('Remove a dependency')
11
+ .argument('<craft>', 'Craft name to remove')
12
+ .action(async (craftName) => {
13
+ await removeCommand(craftName);
14
+ });
15
+ }
16
+ async function removeCommand(craftName) {
17
+ try {
18
+ // Read craftdesk.json
19
+ const craftDeskJson = await (0, file_system_1.readCraftDeskJson)();
20
+ if (!craftDeskJson) {
21
+ logger_1.logger.error('No craftdesk.json found in current directory');
22
+ process.exit(1);
23
+ }
24
+ // Check if craft exists in any dependency field
25
+ let found = false;
26
+ let foundInField = null;
27
+ const depFields = ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'];
28
+ for (const field of depFields) {
29
+ if (craftDeskJson[field] && craftDeskJson[field][craftName]) {
30
+ found = true;
31
+ foundInField = field;
32
+ delete craftDeskJson[field][craftName];
33
+ // Remove empty objects
34
+ if (Object.keys(craftDeskJson[field]).length === 0) {
35
+ delete craftDeskJson[field];
36
+ }
37
+ break;
38
+ }
39
+ }
40
+ if (!found) {
41
+ logger_1.logger.error(`Craft '${craftName}' is not in craftdesk.json`);
42
+ process.exit(1);
43
+ }
44
+ // Save updated craftdesk.json
45
+ await (0, file_system_1.writeCraftDeskJson)(craftDeskJson);
46
+ logger_1.logger.success(`Removed ${craftName} from ${foundInField}`);
47
+ // Read lockfile to get craft type
48
+ const lockfile = await (0, file_system_1.readCraftDeskLock)();
49
+ if (lockfile && lockfile.crafts[craftName]) {
50
+ const craftEntry = lockfile.crafts[craftName];
51
+ // Remove from file system
52
+ await installer_1.installer.removeCraft(craftName, craftEntry.type);
53
+ // Remove from lockfile
54
+ delete lockfile.crafts[craftName];
55
+ // TODO: Clean up dependency tree in lockfile
56
+ // Save updated lockfile
57
+ await (0, file_system_1.writeCraftDeskLock)(lockfile);
58
+ logger_1.logger.success('Updated craftdesk.lock');
59
+ }
60
+ else {
61
+ // Try to remove from file system anyway (best effort)
62
+ const typesToTry = ['skill', 'agent', 'command', 'hook', 'plugin'];
63
+ for (const type of typesToTry) {
64
+ await installer_1.installer.removeCraft(craftName, type);
65
+ }
66
+ }
67
+ logger_1.logger.success('Craft removed successfully!');
68
+ }
69
+ catch (error) {
70
+ logger_1.logger.error(`Failed to remove craft: ${error.message}`);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ //# sourceMappingURL=remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const init_1 = require("./commands/init");
6
+ const install_1 = require("./commands/install");
7
+ const add_1 = require("./commands/add");
8
+ const remove_1 = require("./commands/remove");
9
+ const list_1 = require("./commands/list");
10
+ const logger_1 = require("./utils/logger");
11
+ const program = new commander_1.Command();
12
+ program
13
+ .name('craftdesk')
14
+ .description('CLI for managing CraftDesk AI capabilities')
15
+ .version('0.3.0', '-v, --version')
16
+ .option('-d, --debug', 'Enable debug output', () => {
17
+ process.env.DEBUG = 'true';
18
+ });
19
+ // Add commands
20
+ program.addCommand((0, init_1.createInitCommand)());
21
+ program.addCommand((0, install_1.createInstallCommand)());
22
+ program.addCommand((0, add_1.createAddCommand)());
23
+ program.addCommand((0, remove_1.createRemoveCommand)());
24
+ program.addCommand((0, list_1.createListCommand)());
25
+ // Add aliases
26
+ program.command('i', { hidden: true }).action(() => {
27
+ program.parse(['', '', 'install', ...process.argv.slice(3)]);
28
+ });
29
+ // Error handling
30
+ program.on('command:*', () => {
31
+ logger_1.logger.error(`Invalid command: ${program.args.join(' ')}`);
32
+ logger_1.logger.info('Run "craftdesk --help" for a list of available commands');
33
+ process.exit(1);
34
+ });
35
+ // Show help if no command provided
36
+ if (process.argv.length === 2) {
37
+ logger_1.logger.log('🚀 CraftDesk CLI');
38
+ logger_1.logger.log('');
39
+ logger_1.logger.log('Dependency management for AI capabilities');
40
+ logger_1.logger.log('');
41
+ logger_1.logger.log('Getting started:');
42
+ logger_1.logger.log(' craftdesk init Create a new craftdesk.json file');
43
+ logger_1.logger.log(' craftdesk install Install all dependencies');
44
+ logger_1.logger.log(' craftdesk add <pkg> Add a new dependency');
45
+ logger_1.logger.log('');
46
+ logger_1.logger.log('Run "craftdesk --help" for full command list');
47
+ process.exit(0);
48
+ }
49
+ // Parse command line arguments
50
+ program.parse(process.argv);
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,0CAAoD;AACpD,gDAA0D;AAC1D,wCAAkD;AAClD,8CAAwD;AACxD,0CAAoD;AACpD,2CAAwC;AAExC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,4CAA4C,CAAC;KACzD,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC;KACjC,MAAM,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,eAAe;AACf,OAAO,CAAC,UAAU,CAAC,IAAA,wBAAiB,GAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,IAAA,8BAAoB,GAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,IAAA,sBAAgB,GAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,IAAA,4BAAmB,GAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,IAAA,wBAAiB,GAAE,CAAC,CAAC;AAExC,cAAc;AACd,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;IACjD,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC;AAEH,iBAAiB;AACjB,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;IAC3B,eAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3D,eAAM,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,mCAAmC;AACnC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC9B,eAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC/B,eAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,eAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACxD,eAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,eAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC/B,eAAM,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACtE,eAAM,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC9D,eAAM,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC1D,eAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,eAAM,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,+BAA+B;AAC/B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,88 @@
1
+ import { CraftDeskJson } from '../types/craftdesk-json';
2
+ /**
3
+ * Manages configuration for the CraftDesk CLI
4
+ *
5
+ * Handles reading craftdesk.json, resolving registry URLs for crafts,
6
+ * managing authentication tokens, and determining installation paths.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const configManager = new ConfigManager();
11
+ * const registry = await configManager.getRegistryForCraft('@company/auth');
12
+ * const token = await configManager.getAuthToken('company-private');
13
+ * ```
14
+ */
15
+ export declare class ConfigManager {
16
+ private craftDeskJson;
17
+ /**
18
+ * Gets the appropriate registry URL for a given craft
19
+ *
20
+ * Resolution order:
21
+ * 1. Scoped registry matching the craft scope (e.g., @company/craft -> company registry)
22
+ * 2. Default registry from craftdesk.json
23
+ * 3. Global fallback (https://craftdesk.ai)
24
+ *
25
+ * @param craftName - The name of the craft to resolve
26
+ * @returns The registry URL to use for this craft
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Scoped craft with configured registry
31
+ * const url = await configManager.getRegistryForCraft('@company/auth');
32
+ * // Returns: 'https://company.internal'
33
+ *
34
+ * // Regular craft
35
+ * const url = await configManager.getRegistryForCraft('ruby-on-rails');
36
+ * // Returns: 'https://craftdesk.ai' (or default from config)
37
+ * ```
38
+ */
39
+ getRegistryForCraft(craftName: string): Promise<string>;
40
+ /**
41
+ * Retrieves authentication token for a registry from environment variables
42
+ *
43
+ * Looks for tokens in environment variables with the pattern:
44
+ * CRAFTDESK_AUTH_{REGISTRY_NAME_UPPERCASE}
45
+ *
46
+ * Hyphens in registry names are converted to underscores.
47
+ *
48
+ * @param registryName - The name of the registry from craftdesk.json
49
+ * @returns The auth token if found, null otherwise
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * // For registry named 'company-private', looks for CRAFTDESK_AUTH_COMPANY_PRIVATE
54
+ * const token = await configManager.getAuthToken('company-private');
55
+ *
56
+ * // Usage in shell:
57
+ * // export CRAFTDESK_AUTH_COMPANY_PRIVATE=token_abc123
58
+ * ```
59
+ */
60
+ getAuthToken(registryName: string): Promise<string | null>;
61
+ /**
62
+ * Returns the installation path for crafts
63
+ *
64
+ * All crafts are installed to the .claude directory in the project root.
65
+ *
66
+ * @returns The relative path to the installation directory
67
+ */
68
+ getInstallPath(): string;
69
+ /**
70
+ * Reads and caches the craftdesk.json file from the current working directory
71
+ *
72
+ * The file is cached after the first read for performance. Returns null if
73
+ * the file doesn't exist or contains invalid JSON.
74
+ *
75
+ * @returns The parsed craftdesk.json content, or null if not found/invalid
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const config = await configManager.getCraftDeskJson();
80
+ * if (config) {
81
+ * console.log(`Project: ${config.name}@${config.version}`);
82
+ * }
83
+ * ```
84
+ */
85
+ getCraftDeskJson(): Promise<CraftDeskJson | null>;
86
+ }
87
+ export declare const configManager: ConfigManager;
88
+ //# sourceMappingURL=config-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../src/services/config-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAA8B;IAEnD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6B7D;;;;;;;;;;;;;;;;;;;OAmBG;IACG,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAahE;;;;;;OAMG;IACH,cAAc,IAAI,MAAM;IAKxB;;;;;;;;;;;;;;;OAeG;IACG,gBAAgB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;CAcxD;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}