craftdesk 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -0
- package/README.md +1609 -132
- package/dist/commands/add.d.ts +5 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +306 -8
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/convert.d.ts +8 -0
- package/dist/commands/convert.d.ts.map +1 -0
- package/dist/commands/convert.js +146 -0
- package/dist/commands/convert.js.map +1 -0
- package/dist/commands/detect-agents.d.ts +14 -0
- package/dist/commands/detect-agents.d.ts.map +1 -0
- package/dist/commands/detect-agents.js +86 -0
- package/dist/commands/detect-agents.js.map +1 -0
- package/dist/commands/embed.d.ts +14 -0
- package/dist/commands/embed.d.ts.map +1 -0
- package/dist/commands/embed.js +147 -0
- package/dist/commands/embed.js.map +1 -0
- package/dist/commands/info.d.ts +8 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +66 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +8 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts +5 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +24 -4
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +75 -7
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/login.d.ts +8 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +158 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +8 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +51 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/outdated.d.ts +23 -0
- package/dist/commands/outdated.d.ts.map +1 -0
- package/dist/commands/outdated.js +268 -0
- package/dist/commands/outdated.js.map +1 -0
- package/dist/commands/publish.d.ts +8 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +203 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/remove.d.ts +5 -0
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +51 -10
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/search.d.ts +8 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +60 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/setup-multi-agent.d.ts +17 -0
- package/dist/commands/setup-multi-agent.d.ts.map +1 -0
- package/dist/commands/setup-multi-agent.js +188 -0
- package/dist/commands/setup-multi-agent.js.map +1 -0
- package/dist/commands/sync.d.ts +14 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +144 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/unembed.d.ts +14 -0
- package/dist/commands/unembed.d.ts.map +1 -0
- package/dist/commands/unembed.js +96 -0
- package/dist/commands/unembed.js.map +1 -0
- package/dist/commands/update.d.ts +8 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +372 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +14 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +143 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/whoami.d.ts +8 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +58 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/converters/base-converter.d.ts +89 -0
- package/dist/converters/base-converter.d.ts.map +1 -0
- package/dist/converters/base-converter.js +249 -0
- package/dist/converters/base-converter.js.map +1 -0
- package/dist/converters/continue-converter.d.ts +53 -0
- package/dist/converters/continue-converter.d.ts.map +1 -0
- package/dist/converters/continue-converter.js +243 -0
- package/dist/converters/continue-converter.js.map +1 -0
- package/dist/converters/cursor-converter.d.ts +70 -0
- package/dist/converters/cursor-converter.d.ts.map +1 -0
- package/dist/converters/cursor-converter.js +272 -0
- package/dist/converters/cursor-converter.js.map +1 -0
- package/dist/index.js +56 -3
- package/dist/index.js.map +1 -1
- package/dist/services/agent-detector.d.ts +57 -0
- package/dist/services/agent-detector.d.ts.map +1 -0
- package/dist/services/agent-detector.js +146 -0
- package/dist/services/agent-detector.js.map +1 -0
- package/dist/services/config-manager.d.ts +128 -10
- package/dist/services/config-manager.d.ts.map +1 -1
- package/dist/services/config-manager.js +190 -18
- package/dist/services/config-manager.js.map +1 -1
- package/dist/services/converter.d.ts +53 -0
- package/dist/services/converter.d.ts.map +1 -0
- package/dist/services/converter.js +185 -0
- package/dist/services/converter.js.map +1 -0
- package/dist/services/craft-wrapper.d.ts +108 -0
- package/dist/services/craft-wrapper.d.ts.map +1 -0
- package/dist/services/craft-wrapper.js +268 -0
- package/dist/services/craft-wrapper.js.map +1 -0
- package/dist/services/git-resolver.d.ts +9 -3
- package/dist/services/git-resolver.d.ts.map +1 -1
- package/dist/services/git-resolver.js +44 -20
- package/dist/services/git-resolver.js.map +1 -1
- package/dist/services/gitignore-manager.d.ts +74 -0
- package/dist/services/gitignore-manager.d.ts.map +1 -0
- package/dist/services/gitignore-manager.js +188 -0
- package/dist/services/gitignore-manager.js.map +1 -0
- package/dist/services/installer.d.ts +60 -1
- package/dist/services/installer.d.ts.map +1 -1
- package/dist/services/installer.js +295 -20
- package/dist/services/installer.js.map +1 -1
- package/dist/services/multi-agent-sync.d.ts +88 -0
- package/dist/services/multi-agent-sync.d.ts.map +1 -0
- package/dist/services/multi-agent-sync.js +316 -0
- package/dist/services/multi-agent-sync.js.map +1 -0
- package/dist/services/plugin-resolver.d.ts +80 -0
- package/dist/services/plugin-resolver.d.ts.map +1 -0
- package/dist/services/plugin-resolver.js +183 -0
- package/dist/services/plugin-resolver.js.map +1 -0
- package/dist/services/registry-client.d.ts +132 -5
- package/dist/services/registry-client.d.ts.map +1 -1
- package/dist/services/registry-client.js +239 -34
- package/dist/services/registry-client.js.map +1 -1
- package/dist/services/settings-manager.d.ts +151 -0
- package/dist/services/settings-manager.d.ts.map +1 -0
- package/dist/services/settings-manager.js +333 -0
- package/dist/services/settings-manager.js.map +1 -0
- package/dist/types/claude-settings.d.ts +155 -0
- package/dist/types/claude-settings.d.ts.map +1 -0
- package/dist/types/claude-settings.js +20 -0
- package/dist/types/claude-settings.js.map +1 -0
- package/dist/types/converter.d.ts +98 -0
- package/dist/types/converter.d.ts.map +1 -0
- package/dist/types/converter.js +6 -0
- package/dist/types/converter.js.map +1 -0
- package/dist/types/craftdesk-json.d.ts +76 -3
- package/dist/types/craftdesk-json.d.ts.map +1 -1
- package/dist/types/craftdesk-lock.d.ts +62 -1
- package/dist/types/craftdesk-lock.d.ts.map +1 -1
- package/dist/types/multi-agent.d.ts +85 -0
- package/dist/types/multi-agent.d.ts.map +1 -0
- package/dist/types/multi-agent.js +6 -0
- package/dist/types/multi-agent.js.map +1 -0
- package/dist/utils/crypto.d.ts +23 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +52 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/file-system.d.ts +43 -0
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +45 -2
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/logger.d.ts +75 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +76 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/version-utils.d.ts +63 -0
- package/dist/utils/version-utils.d.ts.map +1 -0
- package/dist/utils/version-utils.js +130 -0
- package/dist/utils/version-utils.js.map +1 -0
- package/package.json +36 -9
- package/.claude/settings.local.json +0 -19
- package/.github/workflows/ci.yml +0 -94
- package/API.md +0 -414
- package/TESTING.md +0 -263
- package/dist/commands/config.d.ts +0 -3
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js +0 -56
- package/dist/commands/config.js.map +0 -1
- package/dist/types/config.d.ts +0 -17
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js +0 -3
- package/dist/types/config.js.map +0 -1
- package/docs/DEPENDENCY_RESOLUTION.md +0 -237
- package/examples/craftdesk-all-sources.json +0 -79
- package/examples/craftdesk-git-monorepo.json +0 -41
- package/examples/craftdesk-multi-registry.json +0 -40
- package/examples/craftdesk-with-registries.json +0 -49
- package/examples/simple-craftdesk.json +0 -10
- package/src/commands/add.ts +0 -314
- package/src/commands/init.ts +0 -55
- package/src/commands/install.ts +0 -126
- package/src/commands/list.ts +0 -126
- package/src/commands/remove.ts +0 -82
- package/src/index.ts +0 -56
- package/src/services/config-manager.ts +0 -150
- package/src/services/git-resolver.ts +0 -373
- package/src/services/installer.ts +0 -314
- package/src/services/registry-client.ts +0 -163
- package/src/types/craftdesk-json.ts +0 -53
- package/src/types/craftdesk-lock.ts +0 -38
- package/src/utils/file-system.ts +0 -55
- package/src/utils/logger.ts +0 -82
- package/tests/fixtures/craftdesk-git.json +0 -17
- package/tests/fixtures/craftdesk.json +0 -15
- package/tests/helpers/test-utils.ts +0 -60
- package/tests/integration/init-command.test.ts +0 -70
- package/tests/integration/list-command.test.ts +0 -77
- package/tests/unit/config-manager.test.ts +0 -228
- package/tests/unit/git-resolver.test.ts +0 -303
- package/tests/unit/installer.test.ts +0 -105
- package/tsconfig.json +0 -20
- package/vitest.config.ts +0 -29
package/src/commands/list.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { readCraftDeskJson, readCraftDeskLock } from '../utils/file-system';
|
|
3
|
-
import { logger } from '../utils/logger';
|
|
4
|
-
import { installer } from '../services/installer';
|
|
5
|
-
|
|
6
|
-
export function createListCommand(): Command {
|
|
7
|
-
return new Command('list')
|
|
8
|
-
.description('List installed crafts')
|
|
9
|
-
.option('--tree', 'Show dependency tree')
|
|
10
|
-
.option('--depth <n>', 'Limit tree depth', parseInt)
|
|
11
|
-
.option('--json', 'Output as JSON')
|
|
12
|
-
.action(async (options) => {
|
|
13
|
-
await listCommand(options);
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function listCommand(options: any): Promise<void> {
|
|
18
|
-
try {
|
|
19
|
-
// Read craftdesk.json for project info
|
|
20
|
-
const craftDeskJson = await readCraftDeskJson();
|
|
21
|
-
if (!craftDeskJson) {
|
|
22
|
-
logger.error('No craftdesk.json found in current directory');
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Get installed crafts
|
|
27
|
-
const installedCrafts = await installer.listInstalled();
|
|
28
|
-
|
|
29
|
-
if (options.json) {
|
|
30
|
-
// JSON output
|
|
31
|
-
console.log(JSON.stringify({
|
|
32
|
-
name: craftDeskJson.name,
|
|
33
|
-
version: craftDeskJson.version,
|
|
34
|
-
installedCrafts
|
|
35
|
-
}, null, 2));
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Display project info
|
|
40
|
-
logger.log(`${craftDeskJson.name}@${craftDeskJson.version}`);
|
|
41
|
-
|
|
42
|
-
if (installedCrafts.length === 0) {
|
|
43
|
-
logger.info('No crafts installed');
|
|
44
|
-
logger.info('Run "craftdesk install" to install dependencies');
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (options.tree) {
|
|
49
|
-
// Show dependency tree
|
|
50
|
-
const lockfile = await readCraftDeskLock();
|
|
51
|
-
if (!lockfile) {
|
|
52
|
-
logger.warn('No craftdesk.lock found. Cannot show dependency tree.');
|
|
53
|
-
logger.info('Run "craftdesk install" to generate lockfile');
|
|
54
|
-
} else {
|
|
55
|
-
displayDependencyTree(lockfile, options.depth);
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
// Simple list
|
|
59
|
-
logger.log('\nInstalled crafts:');
|
|
60
|
-
for (const craft of installedCrafts) {
|
|
61
|
-
const typeIcon = getTypeIcon(craft.type);
|
|
62
|
-
logger.log(` ${typeIcon} ${craft.name}@${craft.version} (${craft.type})`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
logger.log('');
|
|
66
|
-
logger.info(`Total: ${installedCrafts.length} crafts installed`);
|
|
67
|
-
}
|
|
68
|
-
} catch (error: any) {
|
|
69
|
-
logger.error(`Failed to list crafts: ${error.message}`);
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function getTypeIcon(type: string): string {
|
|
75
|
-
switch (type) {
|
|
76
|
-
case 'skill':
|
|
77
|
-
return '📚';
|
|
78
|
-
case 'agent':
|
|
79
|
-
return '🤖';
|
|
80
|
-
case 'command':
|
|
81
|
-
return '⚡';
|
|
82
|
-
case 'hook':
|
|
83
|
-
return '🔗';
|
|
84
|
-
default:
|
|
85
|
-
return '📦';
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function displayDependencyTree(lockfile: any, maxDepth?: number): void {
|
|
90
|
-
logger.log('\nDependency tree:');
|
|
91
|
-
|
|
92
|
-
if (!lockfile.tree) {
|
|
93
|
-
logger.warn('No dependency tree information in lockfile');
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const tree = lockfile.tree;
|
|
98
|
-
const depth = 0;
|
|
99
|
-
const prefix = '';
|
|
100
|
-
|
|
101
|
-
for (const [key, value] of Object.entries(tree)) {
|
|
102
|
-
displayTreeNode(key, value, depth, maxDepth || Infinity, prefix, Object.keys(tree).indexOf(key) === Object.keys(tree).length - 1);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function displayTreeNode(key: string, node: any, depth: number, maxDepth: number, prefix: string, isLast: boolean): void {
|
|
107
|
-
if (depth > maxDepth) return;
|
|
108
|
-
|
|
109
|
-
const connector = isLast ? '└── ' : '├── ';
|
|
110
|
-
const [name, version] = key.split('@');
|
|
111
|
-
|
|
112
|
-
logger.log(`${prefix}${connector}${name}@${version}`);
|
|
113
|
-
|
|
114
|
-
if (typeof node === 'object' && node.dependencies && depth < maxDepth) {
|
|
115
|
-
const newPrefix = prefix + (isLast ? ' ' : '│ ');
|
|
116
|
-
const deps = Object.entries(node.dependencies);
|
|
117
|
-
|
|
118
|
-
deps.forEach(([depKey, depValue], index) => {
|
|
119
|
-
const isLastDep = index === deps.length - 1;
|
|
120
|
-
displayTreeNode(depKey, depValue, depth + 1, maxDepth, newPrefix, isLastDep);
|
|
121
|
-
});
|
|
122
|
-
} else if (typeof node === 'string' && node === '(shared)') {
|
|
123
|
-
// Shared dependency indicator
|
|
124
|
-
logger.log(' (shared)');
|
|
125
|
-
}
|
|
126
|
-
}
|
package/src/commands/remove.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { readCraftDeskJson, writeCraftDeskJson, readCraftDeskLock, writeCraftDeskLock } from '../utils/file-system';
|
|
3
|
-
import { logger } from '../utils/logger';
|
|
4
|
-
import { installer } from '../services/installer';
|
|
5
|
-
|
|
6
|
-
export function createRemoveCommand(): Command {
|
|
7
|
-
return new Command('remove')
|
|
8
|
-
.description('Remove a dependency')
|
|
9
|
-
.argument('<craft>', 'Craft name to remove')
|
|
10
|
-
.action(async (craftName: string) => {
|
|
11
|
-
await removeCommand(craftName);
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function removeCommand(craftName: string): Promise<void> {
|
|
16
|
-
try {
|
|
17
|
-
// Read craftdesk.json
|
|
18
|
-
const craftDeskJson = await readCraftDeskJson();
|
|
19
|
-
if (!craftDeskJson) {
|
|
20
|
-
logger.error('No craftdesk.json found in current directory');
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Check if craft exists in any dependency field
|
|
25
|
-
let found = false;
|
|
26
|
-
let foundInField: string | null = null;
|
|
27
|
-
|
|
28
|
-
const depFields = ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'];
|
|
29
|
-
|
|
30
|
-
for (const field of depFields) {
|
|
31
|
-
if (craftDeskJson[field] && craftDeskJson[field][craftName]) {
|
|
32
|
-
found = true;
|
|
33
|
-
foundInField = field;
|
|
34
|
-
delete craftDeskJson[field][craftName];
|
|
35
|
-
|
|
36
|
-
// Remove empty objects
|
|
37
|
-
if (Object.keys(craftDeskJson[field]).length === 0) {
|
|
38
|
-
delete craftDeskJson[field];
|
|
39
|
-
}
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (!found) {
|
|
45
|
-
logger.error(`Craft '${craftName}' is not in craftdesk.json`);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Save updated craftdesk.json
|
|
50
|
-
await writeCraftDeskJson(craftDeskJson);
|
|
51
|
-
logger.success(`Removed ${craftName} from ${foundInField}`);
|
|
52
|
-
|
|
53
|
-
// Read lockfile to get craft type
|
|
54
|
-
const lockfile = await readCraftDeskLock();
|
|
55
|
-
if (lockfile && lockfile.crafts[craftName]) {
|
|
56
|
-
const craftEntry = lockfile.crafts[craftName];
|
|
57
|
-
|
|
58
|
-
// Remove from file system
|
|
59
|
-
await installer.removeCraft(craftName, craftEntry.type);
|
|
60
|
-
|
|
61
|
-
// Remove from lockfile
|
|
62
|
-
delete lockfile.crafts[craftName];
|
|
63
|
-
|
|
64
|
-
// TODO: Clean up dependency tree in lockfile
|
|
65
|
-
|
|
66
|
-
// Save updated lockfile
|
|
67
|
-
await writeCraftDeskLock(lockfile);
|
|
68
|
-
logger.success('Updated craftdesk.lock');
|
|
69
|
-
} else {
|
|
70
|
-
// Try to remove from file system anyway (best effort)
|
|
71
|
-
const typesToTry = ['skill', 'agent', 'command', 'hook', 'plugin'];
|
|
72
|
-
for (const type of typesToTry) {
|
|
73
|
-
await installer.removeCraft(craftName, type);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
logger.success('Craft removed successfully!');
|
|
78
|
-
} catch (error: any) {
|
|
79
|
-
logger.error(`Failed to remove craft: ${error.message}`);
|
|
80
|
-
process.exit(1);
|
|
81
|
-
}
|
|
82
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { createInitCommand } from './commands/init';
|
|
5
|
-
import { createInstallCommand } from './commands/install';
|
|
6
|
-
import { createAddCommand } from './commands/add';
|
|
7
|
-
import { createRemoveCommand } from './commands/remove';
|
|
8
|
-
import { createListCommand } from './commands/list';
|
|
9
|
-
import { logger } from './utils/logger';
|
|
10
|
-
|
|
11
|
-
const program = new Command();
|
|
12
|
-
|
|
13
|
-
program
|
|
14
|
-
.name('craftdesk')
|
|
15
|
-
.description('CLI for managing CraftDesk AI capabilities')
|
|
16
|
-
.version('0.3.0', '-v, --version')
|
|
17
|
-
.option('-d, --debug', 'Enable debug output', () => {
|
|
18
|
-
process.env.DEBUG = 'true';
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// Add commands
|
|
22
|
-
program.addCommand(createInitCommand());
|
|
23
|
-
program.addCommand(createInstallCommand());
|
|
24
|
-
program.addCommand(createAddCommand());
|
|
25
|
-
program.addCommand(createRemoveCommand());
|
|
26
|
-
program.addCommand(createListCommand());
|
|
27
|
-
|
|
28
|
-
// Add aliases
|
|
29
|
-
program.command('i', { hidden: true }).action(() => {
|
|
30
|
-
program.parse(['', '', 'install', ...process.argv.slice(3)]);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Error handling
|
|
34
|
-
program.on('command:*', () => {
|
|
35
|
-
logger.error(`Invalid command: ${program.args.join(' ')}`);
|
|
36
|
-
logger.info('Run "craftdesk --help" for a list of available commands');
|
|
37
|
-
process.exit(1);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// Show help if no command provided
|
|
41
|
-
if (process.argv.length === 2) {
|
|
42
|
-
logger.log('🚀 CraftDesk CLI');
|
|
43
|
-
logger.log('');
|
|
44
|
-
logger.log('Dependency management for AI capabilities');
|
|
45
|
-
logger.log('');
|
|
46
|
-
logger.log('Getting started:');
|
|
47
|
-
logger.log(' craftdesk init Create a new craftdesk.json file');
|
|
48
|
-
logger.log(' craftdesk install Install all dependencies');
|
|
49
|
-
logger.log(' craftdesk add <pkg> Add a new dependency');
|
|
50
|
-
logger.log('');
|
|
51
|
-
logger.log('Run "craftdesk --help" for full command list');
|
|
52
|
-
process.exit(0);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Parse command line arguments
|
|
56
|
-
program.parse(process.argv);
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { CraftDeskJson } from '../types/craftdesk-json';
|
|
4
|
-
import { logger } from '../utils/logger';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Manages configuration for the CraftDesk CLI
|
|
8
|
-
*
|
|
9
|
-
* Handles reading craftdesk.json, resolving registry URLs for crafts,
|
|
10
|
-
* managing authentication tokens, and determining installation paths.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```typescript
|
|
14
|
-
* const configManager = new ConfigManager();
|
|
15
|
-
* const registry = await configManager.getRegistryForCraft('@company/auth');
|
|
16
|
-
* const token = await configManager.getAuthToken('company-private');
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
export class ConfigManager {
|
|
20
|
-
private craftDeskJson: CraftDeskJson | null = null;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Gets the appropriate registry URL for a given craft
|
|
24
|
-
*
|
|
25
|
-
* Resolution order:
|
|
26
|
-
* 1. Scoped registry matching the craft scope (e.g., @company/craft -> company registry)
|
|
27
|
-
* 2. Default registry from craftdesk.json
|
|
28
|
-
* 3. Global fallback (https://craftdesk.ai)
|
|
29
|
-
*
|
|
30
|
-
* @param craftName - The name of the craft to resolve
|
|
31
|
-
* @returns The registry URL to use for this craft
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```typescript
|
|
35
|
-
* // Scoped craft with configured registry
|
|
36
|
-
* const url = await configManager.getRegistryForCraft('@company/auth');
|
|
37
|
-
* // Returns: 'https://company.internal'
|
|
38
|
-
*
|
|
39
|
-
* // Regular craft
|
|
40
|
-
* const url = await configManager.getRegistryForCraft('ruby-on-rails');
|
|
41
|
-
* // Returns: 'https://craftdesk.ai' (or default from config)
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
async getRegistryForCraft(craftName: string): Promise<string> {
|
|
45
|
-
const craftDesk = await this.getCraftDeskJson();
|
|
46
|
-
|
|
47
|
-
if (!craftDesk) {
|
|
48
|
-
// Default registry if no craftdesk.json exists
|
|
49
|
-
return 'https://craftdesk.ai';
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Check if it's a scoped craft and has a configured registry
|
|
53
|
-
if (craftName.startsWith('@') && craftDesk.registries) {
|
|
54
|
-
const scope = craftName.split('/')[0];
|
|
55
|
-
|
|
56
|
-
// Look for a registry with matching scope
|
|
57
|
-
for (const [name, registry] of Object.entries(craftDesk.registries)) {
|
|
58
|
-
if (registry.scope === scope) {
|
|
59
|
-
return registry.url;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Check if there's a default registry configured
|
|
65
|
-
if (craftDesk.registries?.default) {
|
|
66
|
-
return craftDesk.registries.default.url;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Final fallback
|
|
70
|
-
return 'https://craftdesk.ai';
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Retrieves authentication token for a registry from environment variables
|
|
75
|
-
*
|
|
76
|
-
* Looks for tokens in environment variables with the pattern:
|
|
77
|
-
* CRAFTDESK_AUTH_{REGISTRY_NAME_UPPERCASE}
|
|
78
|
-
*
|
|
79
|
-
* Hyphens in registry names are converted to underscores.
|
|
80
|
-
*
|
|
81
|
-
* @param registryName - The name of the registry from craftdesk.json
|
|
82
|
-
* @returns The auth token if found, null otherwise
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* ```typescript
|
|
86
|
-
* // For registry named 'company-private', looks for CRAFTDESK_AUTH_COMPANY_PRIVATE
|
|
87
|
-
* const token = await configManager.getAuthToken('company-private');
|
|
88
|
-
*
|
|
89
|
-
* // Usage in shell:
|
|
90
|
-
* // export CRAFTDESK_AUTH_COMPANY_PRIVATE=token_abc123
|
|
91
|
-
* ```
|
|
92
|
-
*/
|
|
93
|
-
async getAuthToken(registryName: string): Promise<string | null> {
|
|
94
|
-
const craftDesk = await this.getCraftDeskJson();
|
|
95
|
-
|
|
96
|
-
if (!craftDesk?.registries?.[registryName]) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Auth tokens should be in environment variables for security
|
|
101
|
-
// e.g., CRAFTDESK_AUTH_COMPANY_PRIVATE
|
|
102
|
-
const envVar = `CRAFTDESK_AUTH_${registryName.toUpperCase().replace(/-/g, '_')}`;
|
|
103
|
-
return process.env[envVar] || null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Returns the installation path for crafts
|
|
108
|
-
*
|
|
109
|
-
* All crafts are installed to the .claude directory in the project root.
|
|
110
|
-
*
|
|
111
|
-
* @returns The relative path to the installation directory
|
|
112
|
-
*/
|
|
113
|
-
getInstallPath(): string {
|
|
114
|
-
// Always use .claude directory in project root
|
|
115
|
-
return '.claude';
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Reads and caches the craftdesk.json file from the current working directory
|
|
120
|
-
*
|
|
121
|
-
* The file is cached after the first read for performance. Returns null if
|
|
122
|
-
* the file doesn't exist or contains invalid JSON.
|
|
123
|
-
*
|
|
124
|
-
* @returns The parsed craftdesk.json content, or null if not found/invalid
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* ```typescript
|
|
128
|
-
* const config = await configManager.getCraftDeskJson();
|
|
129
|
-
* if (config) {
|
|
130
|
-
* console.log(`Project: ${config.name}@${config.version}`);
|
|
131
|
-
* }
|
|
132
|
-
* ```
|
|
133
|
-
*/
|
|
134
|
-
async getCraftDeskJson(): Promise<CraftDeskJson | null> {
|
|
135
|
-
if (this.craftDeskJson) {
|
|
136
|
-
return this.craftDeskJson;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
const craftDeskPath = path.join(process.cwd(), 'craftdesk.json');
|
|
141
|
-
const content = await fs.readFile(craftDeskPath, 'utf-8');
|
|
142
|
-
this.craftDeskJson = JSON.parse(content);
|
|
143
|
-
return this.craftDeskJson;
|
|
144
|
-
} catch (error) {
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export const configManager = new ConfigManager();
|