craftdesk 0.2.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.
- package/CHANGELOG.md +57 -0
- package/README.md +968 -92
- package/dist/commands/add.d.ts +5 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +303 -7
- 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/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 +9 -3
- 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 +72 -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 +198 -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 +52 -11
- 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/update.d.ts +8 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +369 -0
- package/dist/commands/update.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 +35 -4
- package/dist/index.js.map +1 -1
- 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 +189 -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 +35 -10
- package/dist/services/git-resolver.js.map +1 -1
- package/dist/services/installer.d.ts +51 -1
- package/dist/services/installer.d.ts.map +1 -1
- package/dist/services/installer.js +245 -14
- package/dist/services/installer.js.map +1 -1
- 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 +182 -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 +63 -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/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 -17
- 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 -370
- 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
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
-
import { GitResolver } from '../../src/services/git-resolver';
|
|
3
|
-
import { createTempDir, cleanupTempDir, writeJsonFile } from '../helpers/test-utils';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import fs from 'fs-extra';
|
|
6
|
-
import { execSync } from 'child_process';
|
|
7
|
-
|
|
8
|
-
// Mock execSync for these tests
|
|
9
|
-
vi.mock('child_process', () => ({
|
|
10
|
-
execSync: vi.fn()
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
describe('GitResolver', () => {
|
|
14
|
-
let gitResolver: GitResolver;
|
|
15
|
-
let tempDir: string;
|
|
16
|
-
|
|
17
|
-
beforeEach(async () => {
|
|
18
|
-
gitResolver = new GitResolver();
|
|
19
|
-
tempDir = await createTempDir('git-test-');
|
|
20
|
-
vi.clearAllMocks();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
afterEach(async () => {
|
|
24
|
-
await cleanupTempDir(tempDir);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe('inferCraftType', () => {
|
|
28
|
-
it('should infer skill type from SKILL.md marker file', async () => {
|
|
29
|
-
const testDir = await createTempDir('type-test-');
|
|
30
|
-
await fs.writeFile(path.join(testDir, 'SKILL.md'), '# Skill');
|
|
31
|
-
|
|
32
|
-
// Access private method via type assertion
|
|
33
|
-
const type = await (gitResolver as any).inferCraftType(testDir);
|
|
34
|
-
|
|
35
|
-
expect(type).toBe('skill');
|
|
36
|
-
await cleanupTempDir(testDir);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should infer agent type from AGENT.md marker file', async () => {
|
|
40
|
-
const testDir = await createTempDir('type-test-');
|
|
41
|
-
await fs.writeFile(path.join(testDir, 'AGENT.md'), '# Agent');
|
|
42
|
-
|
|
43
|
-
const type = await (gitResolver as any).inferCraftType(testDir);
|
|
44
|
-
|
|
45
|
-
expect(type).toBe('agent');
|
|
46
|
-
await cleanupTempDir(testDir);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should infer command type from COMMAND.md marker file', async () => {
|
|
50
|
-
const testDir = await createTempDir('type-test-');
|
|
51
|
-
await fs.writeFile(path.join(testDir, 'COMMAND.md'), '# Command');
|
|
52
|
-
|
|
53
|
-
const type = await (gitResolver as any).inferCraftType(testDir);
|
|
54
|
-
|
|
55
|
-
expect(type).toBe('command');
|
|
56
|
-
await cleanupTempDir(testDir);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should infer hook type from HOOK.md marker file', async () => {
|
|
60
|
-
const testDir = await createTempDir('type-test-');
|
|
61
|
-
await fs.writeFile(path.join(testDir, 'HOOK.md'), '# Hook');
|
|
62
|
-
|
|
63
|
-
const type = await (gitResolver as any).inferCraftType(testDir);
|
|
64
|
-
|
|
65
|
-
expect(type).toBe('hook');
|
|
66
|
-
await cleanupTempDir(testDir);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should infer type from directory name containing "skill"', async () => {
|
|
70
|
-
const testDir = await createTempDir('my-skill-');
|
|
71
|
-
|
|
72
|
-
const type = await (gitResolver as any).inferCraftType(testDir);
|
|
73
|
-
|
|
74
|
-
expect(type).toBe('skill');
|
|
75
|
-
await cleanupTempDir(testDir);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should infer type from directory name containing "agent"', async () => {
|
|
79
|
-
const testDir = path.join(tempDir, 'my-agent');
|
|
80
|
-
await fs.ensureDir(testDir);
|
|
81
|
-
|
|
82
|
-
const type = await (gitResolver as any).inferCraftType(testDir);
|
|
83
|
-
|
|
84
|
-
expect(type).toBe('agent');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should default to skill when no indicators found', async () => {
|
|
88
|
-
const testDir = await createTempDir('random-name-');
|
|
89
|
-
|
|
90
|
-
const type = await (gitResolver as any).inferCraftType(testDir);
|
|
91
|
-
|
|
92
|
-
expect(type).toBe('skill');
|
|
93
|
-
await cleanupTempDir(testDir);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
describe('resolveGitDependency', () => {
|
|
98
|
-
it('should resolve git dependency with craftdesk.json', async () => {
|
|
99
|
-
const mockRepoPath = path.join(tempDir, 'mock-repo');
|
|
100
|
-
await fs.ensureDir(mockRepoPath);
|
|
101
|
-
|
|
102
|
-
const craftDeskJson = {
|
|
103
|
-
name: 'test-skill',
|
|
104
|
-
version: '1.0.0',
|
|
105
|
-
type: 'skill',
|
|
106
|
-
description: 'Test skill',
|
|
107
|
-
dependencies: {
|
|
108
|
-
'helper-lib': '^1.0.0'
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
await writeJsonFile(path.join(mockRepoPath, 'craftdesk.json'), craftDeskJson);
|
|
113
|
-
|
|
114
|
-
// Mock git commands
|
|
115
|
-
const mockExecSync = vi.mocked(execSync);
|
|
116
|
-
mockExecSync.mockImplementation((cmd: any, options?: any) => {
|
|
117
|
-
const cmdStr = cmd.toString();
|
|
118
|
-
if (cmdStr.includes('git clone')) {
|
|
119
|
-
// Simulate successful clone by copying our mock repo
|
|
120
|
-
const targetMatch = cmdStr.match(/git clone.*\s+(.+)$/);
|
|
121
|
-
if (targetMatch) {
|
|
122
|
-
fs.copySync(mockRepoPath, targetMatch[1]);
|
|
123
|
-
}
|
|
124
|
-
return Buffer.from('');
|
|
125
|
-
} else if (cmdStr.includes('git rev-parse HEAD')) {
|
|
126
|
-
const output = 'abc123def456789012345678901234567890abcd\n';
|
|
127
|
-
return options?.encoding === 'utf8' ? output : Buffer.from(output);
|
|
128
|
-
}
|
|
129
|
-
return Buffer.from('');
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
const result = await gitResolver.resolveGitDependency({
|
|
133
|
-
url: 'https://github.com/test/repo.git',
|
|
134
|
-
branch: 'main'
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
expect(result.craftDeskJson).toEqual(craftDeskJson);
|
|
138
|
-
expect(result.resolvedCommit).toBe('abc123def456789012345678901234567890abcd');
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('should generate minimal metadata when craftdesk.json is missing', async () => {
|
|
142
|
-
const mockRepoPath = path.join(tempDir, 'mock-repo-no-json');
|
|
143
|
-
await fs.ensureDir(mockRepoPath);
|
|
144
|
-
await fs.writeFile(path.join(mockRepoPath, 'SKILL.md'), '# Skill');
|
|
145
|
-
|
|
146
|
-
const mockExecSync = vi.mocked(execSync);
|
|
147
|
-
mockExecSync.mockImplementation((cmd: any, options?: any) => {
|
|
148
|
-
const cmdStr = cmd.toString();
|
|
149
|
-
if (cmdStr.includes('git clone')) {
|
|
150
|
-
const targetMatch = cmdStr.match(/git clone.*\s+(.+)$/);
|
|
151
|
-
if (targetMatch) {
|
|
152
|
-
fs.copySync(mockRepoPath, targetMatch[1]);
|
|
153
|
-
}
|
|
154
|
-
return Buffer.from('');
|
|
155
|
-
} else if (cmdStr.includes('git rev-parse HEAD')) {
|
|
156
|
-
const output = 'abc123def456789012345678901234567890abcd\n';
|
|
157
|
-
return options?.encoding === 'utf8' ? output : Buffer.from(output);
|
|
158
|
-
}
|
|
159
|
-
return Buffer.from('');
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
const result = await gitResolver.resolveGitDependency({
|
|
163
|
-
url: 'https://github.com/test/repo.git',
|
|
164
|
-
branch: 'main'
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
expect(result.craftDeskJson).toBeDefined();
|
|
168
|
-
expect(result.craftDeskJson!.name).toBe('repo');
|
|
169
|
-
expect(result.craftDeskJson!.version).toBe('main');
|
|
170
|
-
expect(result.craftDeskJson!.type).toBe('skill');
|
|
171
|
-
expect(result.craftDeskJson!.dependencies).toEqual({});
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it('should handle subdirectory path for monorepos', async () => {
|
|
175
|
-
const mockRepoPath = path.join(tempDir, 'mock-monorepo');
|
|
176
|
-
const skillPath = path.join(mockRepoPath, 'packages', 'auth');
|
|
177
|
-
await fs.ensureDir(skillPath);
|
|
178
|
-
|
|
179
|
-
const craftDeskJson = {
|
|
180
|
-
name: 'auth-skill',
|
|
181
|
-
version: '2.0.0',
|
|
182
|
-
type: 'skill',
|
|
183
|
-
dependencies: {}
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
await writeJsonFile(path.join(skillPath, 'craftdesk.json'), craftDeskJson);
|
|
187
|
-
|
|
188
|
-
const mockExecSync = vi.mocked(execSync);
|
|
189
|
-
mockExecSync.mockImplementation((cmd: any, options?: any) => {
|
|
190
|
-
const cmdStr = cmd.toString();
|
|
191
|
-
if (cmdStr.includes('git clone')) {
|
|
192
|
-
const targetMatch = cmdStr.match(/git clone.*\s+(.+)$/);
|
|
193
|
-
if (targetMatch) {
|
|
194
|
-
fs.copySync(mockRepoPath, targetMatch[1]);
|
|
195
|
-
}
|
|
196
|
-
return Buffer.from('');
|
|
197
|
-
} else if (cmdStr.includes('git rev-parse HEAD')) {
|
|
198
|
-
const output = 'def456789012345678901234567890abcdef123\n';
|
|
199
|
-
return options?.encoding === 'utf8' ? output : Buffer.from(output);
|
|
200
|
-
}
|
|
201
|
-
return Buffer.from('');
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
const result = await gitResolver.resolveGitDependency({
|
|
205
|
-
url: 'https://github.com/test/monorepo.git',
|
|
206
|
-
tag: 'v2.0.0',
|
|
207
|
-
path: 'packages/auth'
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
expect(result.craftDeskJson).toEqual(craftDeskJson);
|
|
211
|
-
expect(result.path).toBe('packages/auth');
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
describe('resolveAllDependencies', () => {
|
|
216
|
-
it('should resolve registry dependencies', async () => {
|
|
217
|
-
const dependencies = {
|
|
218
|
-
'ruby-on-rails': '^7.0.0',
|
|
219
|
-
'postgres-expert': '^1.0.0'
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
const result = await gitResolver.resolveAllDependencies(dependencies);
|
|
223
|
-
|
|
224
|
-
expect(result.resolved['ruby-on-rails']).toEqual({
|
|
225
|
-
needsResolution: true,
|
|
226
|
-
version: '^7.0.0',
|
|
227
|
-
registry: undefined
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
expect(result.resolved['postgres-expert']).toEqual({
|
|
231
|
-
needsResolution: true,
|
|
232
|
-
version: '^1.0.0',
|
|
233
|
-
registry: undefined
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it('should resolve mixed git and registry dependencies', async () => {
|
|
238
|
-
const mockRepoPath = path.join(tempDir, 'mock-git-dep');
|
|
239
|
-
await fs.ensureDir(mockRepoPath);
|
|
240
|
-
|
|
241
|
-
const craftDeskJson = {
|
|
242
|
-
name: 'custom-auth',
|
|
243
|
-
version: '1.0.0',
|
|
244
|
-
type: 'agent',
|
|
245
|
-
dependencies: {
|
|
246
|
-
'jwt-helper': '^2.0.0'
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
await writeJsonFile(path.join(mockRepoPath, 'craftdesk.json'), craftDeskJson);
|
|
251
|
-
|
|
252
|
-
const mockExecSync = vi.mocked(execSync);
|
|
253
|
-
mockExecSync.mockImplementation((cmd: any, options?: any) => {
|
|
254
|
-
const cmdStr = cmd.toString();
|
|
255
|
-
if (cmdStr.includes('git clone')) {
|
|
256
|
-
const targetMatch = cmdStr.match(/git clone.*\s+(.+)$/);
|
|
257
|
-
if (targetMatch) {
|
|
258
|
-
fs.copySync(mockRepoPath, targetMatch[1]);
|
|
259
|
-
}
|
|
260
|
-
return Buffer.from('');
|
|
261
|
-
} else if (cmdStr.includes('git rev-parse HEAD')) {
|
|
262
|
-
const output = 'abc123def456789012345678901234567890abcd\n';
|
|
263
|
-
return options?.encoding === 'utf8' ? output : Buffer.from(output);
|
|
264
|
-
}
|
|
265
|
-
return Buffer.from('');
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
const dependencies = {
|
|
269
|
-
'ruby-on-rails': '^7.0.0',
|
|
270
|
-
'custom-auth': {
|
|
271
|
-
git: 'https://github.com/company/auth.git',
|
|
272
|
-
branch: 'main'
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
const result = await gitResolver.resolveAllDependencies(dependencies);
|
|
277
|
-
|
|
278
|
-
// Check registry dependency
|
|
279
|
-
expect(result.resolved['ruby-on-rails'].needsResolution).toBe(true);
|
|
280
|
-
|
|
281
|
-
// Check git dependency
|
|
282
|
-
expect(result.resolved['custom-auth'].git).toBe('https://github.com/company/auth.git');
|
|
283
|
-
expect(result.resolved['custom-auth'].branch).toBe('main');
|
|
284
|
-
expect(result.resolved['custom-auth'].type).toBe('agent');
|
|
285
|
-
|
|
286
|
-
// Check transitive dependency from git
|
|
287
|
-
expect(result.resolved['jwt-helper']).toBeDefined();
|
|
288
|
-
expect(result.resolved['jwt-helper'].version).toBe('^2.0.0');
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
it('should avoid circular dependencies', async () => {
|
|
292
|
-
const dependencies = {
|
|
293
|
-
'package-a': '^1.0.0'
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
// The algorithm marks visited packages to avoid infinite loops
|
|
297
|
-
const result = await gitResolver.resolveAllDependencies(dependencies);
|
|
298
|
-
|
|
299
|
-
expect(result.resolved['package-a']).toBeDefined();
|
|
300
|
-
expect(result.lockfile.crafts).toBeDefined();
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
});
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
-
import { Installer } from '../../src/services/installer';
|
|
3
|
-
import { createTempDir, cleanupTempDir } from '../helpers/test-utils';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
describe('Installer', () => {
|
|
7
|
-
let installer: Installer;
|
|
8
|
-
let tempDir: string;
|
|
9
|
-
let originalCwd: string;
|
|
10
|
-
|
|
11
|
-
beforeEach(async () => {
|
|
12
|
-
installer = new Installer();
|
|
13
|
-
tempDir = await createTempDir('installer-test-');
|
|
14
|
-
originalCwd = process.cwd();
|
|
15
|
-
process.chdir(tempDir);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
afterEach(async () => {
|
|
19
|
-
process.chdir(originalCwd);
|
|
20
|
-
await cleanupTempDir(tempDir);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
describe('getTypeDirectory', () => {
|
|
24
|
-
it('should return correct directory for skill type', () => {
|
|
25
|
-
const result = (installer as any).getTypeDirectory('skill');
|
|
26
|
-
expect(result).toBe('skills');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should return correct directory for agent type', () => {
|
|
30
|
-
const result = (installer as any).getTypeDirectory('agent');
|
|
31
|
-
expect(result).toBe('agents');
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should return correct directory for command type', () => {
|
|
35
|
-
const result = (installer as any).getTypeDirectory('command');
|
|
36
|
-
expect(result).toBe('commands');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should return correct directory for hook type', () => {
|
|
40
|
-
const result = (installer as any).getTypeDirectory('hook');
|
|
41
|
-
expect(result).toBe('hooks');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should default to crafts for unknown type', () => {
|
|
45
|
-
const result = (installer as any).getTypeDirectory('unknown' as any);
|
|
46
|
-
expect(result).toBe('crafts');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe('createMetadata', () => {
|
|
51
|
-
it('should create craftdesk-metadata.json file', async () => {
|
|
52
|
-
const fs = await import('fs-extra');
|
|
53
|
-
const craftDir = path.join(tempDir, '.claude', 'skills', 'test-craft');
|
|
54
|
-
await fs.ensureDir(craftDir);
|
|
55
|
-
|
|
56
|
-
const entry = {
|
|
57
|
-
version: '1.0.0',
|
|
58
|
-
resolved: 'https://craftdesk.ai/download',
|
|
59
|
-
integrity: 'sha256-test',
|
|
60
|
-
type: 'skill' as const,
|
|
61
|
-
author: 'test-author',
|
|
62
|
-
dependencies: {}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
await (installer as any).createMetadata(craftDir, 'test-craft', entry);
|
|
66
|
-
|
|
67
|
-
const metadataPath = path.join(craftDir, '.craftdesk-metadata.json');
|
|
68
|
-
const exists = await fs.pathExists(metadataPath);
|
|
69
|
-
expect(exists).toBe(true);
|
|
70
|
-
|
|
71
|
-
const metadata = await fs.readJson(metadataPath);
|
|
72
|
-
expect(metadata.name).toBe('test-craft');
|
|
73
|
-
expect(metadata.version).toBe('1.0.0');
|
|
74
|
-
expect(metadata.type).toBe('skill');
|
|
75
|
-
expect(metadata.installedAt).toBeDefined();
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
describe('installFromLockfile', () => {
|
|
80
|
-
it('should handle empty lockfile', async () => {
|
|
81
|
-
const lockfile = {
|
|
82
|
-
version: '1.0.0',
|
|
83
|
-
lockfileVersion: 1,
|
|
84
|
-
crafts: {}
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
await expect(installer.installFromLockfile(lockfile)).resolves.not.toThrow();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should create install directory structure', async () => {
|
|
91
|
-
const fs = await import('fs-extra');
|
|
92
|
-
const lockfile = {
|
|
93
|
-
version: '1.0.0',
|
|
94
|
-
lockfileVersion: 1,
|
|
95
|
-
crafts: {}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
await installer.installFromLockfile(lockfile);
|
|
99
|
-
|
|
100
|
-
const installDir = path.join(tempDir, '.claude');
|
|
101
|
-
const exists = await fs.pathExists(installDir);
|
|
102
|
-
expect(exists).toBe(true);
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"lib": ["ES2022"],
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": "./src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"declaration": true,
|
|
14
|
-
"declarationMap": true,
|
|
15
|
-
"sourceMap": true,
|
|
16
|
-
"moduleResolution": "node"
|
|
17
|
-
},
|
|
18
|
-
"include": ["src/**/*"],
|
|
19
|
-
"exclude": ["node_modules", "dist", "tests"]
|
|
20
|
-
}
|
package/vitest.config.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config';
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
environment: 'node',
|
|
7
|
-
pool: 'forks',
|
|
8
|
-
poolOptions: {
|
|
9
|
-
forks: {
|
|
10
|
-
singleFork: true
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
coverage: {
|
|
14
|
-
provider: 'v8',
|
|
15
|
-
reporter: ['text', 'json', 'html'],
|
|
16
|
-
exclude: [
|
|
17
|
-
'node_modules/',
|
|
18
|
-
'dist/',
|
|
19
|
-
'bin/',
|
|
20
|
-
'**/*.d.ts',
|
|
21
|
-
'**/*.config.*',
|
|
22
|
-
'**/mockData/',
|
|
23
|
-
'tests/'
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
include: ['tests/**/*.test.ts'],
|
|
27
|
-
exclude: ['node_modules', 'dist']
|
|
28
|
-
}
|
|
29
|
-
});
|