skillsd 0.1.0 → 0.1.1

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.
@@ -0,0 +1,12 @@
1
+ interface AddSkillOptions {
2
+ global?: boolean;
3
+ agents?: string[];
4
+ list?: boolean;
5
+ yes?: boolean;
6
+ }
7
+ /**
8
+ * Download and extract a skill from SkillsDojo
9
+ */
10
+ export declare function addSkillFromDojo(accountSlug: string, collectionSlug: string, skillPath: string, options: AddSkillOptions): Promise<void>;
11
+ export {};
12
+ //# sourceMappingURL=add-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-skill.d.ts","sourceRoot":"","sources":["../../src/commands/add-skill.ts"],"names":[],"mappings":"AAeA,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAeD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CA+Jf"}
@@ -0,0 +1,164 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import inquirer from 'inquirer';
4
+ import { mkdirSync, existsSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { api } from '../lib/api.js';
7
+ import { requireAuth } from '../lib/auth.js';
8
+ import { unlinkSync } from 'fs';
9
+ import { tmpdir } from 'os';
10
+ import { randomBytes } from 'crypto';
11
+ import { execSync } from 'child_process';
12
+ /**
13
+ * Get the skills installation directory
14
+ */
15
+ function getSkillsDir(global) {
16
+ if (global) {
17
+ // Global: ~/.agents/skills/
18
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
19
+ return join(homeDir, '.agents', 'skills');
20
+ }
21
+ // Local: .agents/skills/ in current directory
22
+ return join(process.cwd(), '.agents', 'skills');
23
+ }
24
+ /**
25
+ * Download and extract a skill from SkillsDojo
26
+ */
27
+ export async function addSkillFromDojo(accountSlug, collectionSlug, skillPath, options) {
28
+ const creds = requireAuth();
29
+ // List mode - just show the skill info
30
+ if (options.list) {
31
+ const spinner = ora('Fetching skill info...').start();
32
+ const collResponse = await api.getCollectionBySlug(accountSlug, collectionSlug);
33
+ if (collResponse.error || !collResponse.data) {
34
+ spinner.fail('Collection not found');
35
+ console.error(chalk.red(collResponse.error?.message || 'Collection not found'));
36
+ console.error(chalk.gray('Make sure you have access to this collection'));
37
+ process.exit(1);
38
+ }
39
+ const skillsResponse = await api.listSkills(collResponse.data.id, { search: skillPath, limit: 100 });
40
+ if (skillsResponse.error || !skillsResponse.data) {
41
+ spinner.fail('Failed to list skills');
42
+ console.error(chalk.red(skillsResponse.error?.message || 'Failed to list skills'));
43
+ process.exit(1);
44
+ }
45
+ const skill = skillsResponse.data.items.find(s => s.path === skillPath);
46
+ if (!skill) {
47
+ spinner.fail(`Skill "${skillPath}" not found in collection`);
48
+ const available = skillsResponse.data.items.map(s => s.path).slice(0, 10);
49
+ if (available.length > 0) {
50
+ console.log(chalk.gray('\nAvailable skills:'));
51
+ available.forEach(s => console.log(chalk.gray(` - ${accountSlug}/${collectionSlug}/${s}`)));
52
+ }
53
+ process.exit(1);
54
+ }
55
+ spinner.stop();
56
+ console.log(`\n${chalk.bold(skill.name)}`);
57
+ console.log(chalk.gray(`${accountSlug}/${collectionSlug}/${skillPath}`));
58
+ if (skill.description) {
59
+ console.log(`\n${skill.description}`);
60
+ }
61
+ console.log(chalk.gray(`\nTo install: skillsd add ${accountSlug}/${collectionSlug}/${skillPath}`));
62
+ return;
63
+ }
64
+ const spinner = ora(`Adding skill from ${accountSlug}/${collectionSlug}...`).start();
65
+ // Get collection by slug
66
+ const collResponse = await api.getCollectionBySlug(accountSlug, collectionSlug);
67
+ if (collResponse.error || !collResponse.data) {
68
+ spinner.fail('Collection not found');
69
+ console.error(chalk.red(collResponse.error?.message || 'Collection not found'));
70
+ console.error(chalk.gray('Make sure you have access to this collection'));
71
+ process.exit(1);
72
+ }
73
+ const collection = collResponse.data;
74
+ // Request download token for specific skill
75
+ spinner.text = 'Requesting download...';
76
+ const tokenResponse = await api.requestSkillsDownloadToken(collection.id, {
77
+ skillPaths: [skillPath],
78
+ });
79
+ if (tokenResponse.error || !tokenResponse.data) {
80
+ spinner.fail('Failed to request download');
81
+ console.error(chalk.red(tokenResponse.error?.message || 'Failed to request download token'));
82
+ process.exit(1);
83
+ }
84
+ const { downloadToken, skills } = tokenResponse.data;
85
+ if (skills.found === 0) {
86
+ spinner.fail(`Skill "${skillPath}" not found in collection`);
87
+ if (skills.notFoundPaths && skills.notFoundPaths.length > 0) {
88
+ console.error(chalk.gray(`Not found: ${skills.notFoundPaths.join(', ')}`));
89
+ }
90
+ process.exit(1);
91
+ }
92
+ // Download to temp file
93
+ spinner.text = 'Downloading skill...';
94
+ const tempFile = join(tmpdir(), `skillsd-${randomBytes(8).toString('hex')}.zip`);
95
+ try {
96
+ await api.downloadZip(collection.id, downloadToken, tempFile);
97
+ }
98
+ catch (error) {
99
+ spinner.fail('Download failed');
100
+ console.error(chalk.red(error instanceof Error ? error.message : 'Download failed'));
101
+ process.exit(1);
102
+ }
103
+ // Determine installation directory
104
+ const skillsDir = getSkillsDir(options.global || false);
105
+ const targetDir = join(skillsDir, skillPath);
106
+ // Check if skill already exists
107
+ if (existsSync(targetDir) && !options.yes) {
108
+ spinner.stop();
109
+ const { overwrite } = await inquirer.prompt([
110
+ {
111
+ type: 'confirm',
112
+ name: 'overwrite',
113
+ message: `Skill "${skillPath}" already exists. Overwrite?`,
114
+ default: false,
115
+ },
116
+ ]);
117
+ if (!overwrite) {
118
+ console.log(chalk.yellow('Installation cancelled'));
119
+ unlinkSync(tempFile);
120
+ process.exit(0);
121
+ }
122
+ spinner.start('Installing skill...');
123
+ }
124
+ // Extract to skills directory
125
+ spinner.text = 'Installing skill...';
126
+ // Create skills directory if it doesn't exist
127
+ if (!existsSync(skillsDir)) {
128
+ mkdirSync(skillsDir, { recursive: true });
129
+ }
130
+ // Extract using unzip command
131
+ try {
132
+ // Extract to a temp directory first
133
+ const extractDir = join(tmpdir(), `skillsd-extract-${randomBytes(8).toString('hex')}`);
134
+ mkdirSync(extractDir, { recursive: true });
135
+ execSync(`unzip -o "${tempFile}" -d "${extractDir}"`, { stdio: 'pipe' });
136
+ // Find the skill directory in extracted files
137
+ const extractedSkillDir = join(extractDir, skillPath);
138
+ if (existsSync(extractedSkillDir)) {
139
+ // Remove existing target if it exists
140
+ if (existsSync(targetDir)) {
141
+ execSync(`rm -rf "${targetDir}"`, { stdio: 'pipe' });
142
+ }
143
+ // Create parent directory and copy contents (not the directory itself)
144
+ mkdirSync(targetDir, { recursive: true });
145
+ execSync(`cp -r "${extractedSkillDir}/"* "${targetDir}/"`, { stdio: 'pipe', shell: '/bin/bash' });
146
+ }
147
+ else {
148
+ throw new Error(`Skill directory not found in archive`);
149
+ }
150
+ // Cleanup
151
+ execSync(`rm -rf "${extractDir}"`, { stdio: 'pipe' });
152
+ }
153
+ catch (error) {
154
+ spinner.fail('Extraction failed');
155
+ console.error(chalk.red(error instanceof Error ? error.message : 'Extraction failed'));
156
+ unlinkSync(tempFile);
157
+ process.exit(1);
158
+ }
159
+ // Cleanup temp file
160
+ unlinkSync(tempFile);
161
+ spinner.succeed(`Added ${chalk.green(skillPath)} from ${accountSlug}/${collectionSlug}`);
162
+ console.log(chalk.gray(` Installed to: ${targetDir}`));
163
+ }
164
+ //# sourceMappingURL=add-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-skill.js","sourceRoot":"","sources":["../../src/commands/add-skill.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"clone.d.ts","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,YAAY,SAgGrB,CAAC"}
1
+ {"version":3,"file":"clone.d.ts","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,YAAY,SAsGrB,CAAC"}
@@ -1,37 +1,39 @@
1
1
  import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import ora from 'ora';
4
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
5
- import { join, dirname } from 'path';
4
+ import { mkdirSync, writeFileSync, existsSync } from 'fs';
5
+ import { join } from 'path';
6
6
  import { api } from '../lib/api.js';
7
- import { saveWorkspaceConfig, saveWorkspaceIndex, getApiUrl } from '../lib/config.js';
7
+ import { requireAuth } from '../lib/auth.js';
8
+ import { saveWorkspaceConfig, saveWorkspaceIndex } from '../lib/config.js';
8
9
  export const cloneCommand = new Command('clone')
9
- .description('Clone a skill collection to local workspace')
10
- .argument('<path>', 'Collection path (account/collection)')
11
- .argument('[directory]', 'Target directory (default: collection name)')
12
- .action(async (path, directory) => {
13
- const [accountSlug, collectionSlug] = path.split('/');
10
+ .description('Clone a collection to work on locally')
11
+ .argument('<collection>', 'Collection to clone (account/collection)')
12
+ .option('-b, --branch <name>', 'Branch to clone', 'main')
13
+ .option('-d, --directory <path>', 'Directory to clone into')
14
+ .action(async (collectionPath, options) => {
15
+ requireAuth();
16
+ const [accountSlug, collectionSlug] = collectionPath.split('/');
14
17
  if (!accountSlug || !collectionSlug) {
15
18
  console.error(chalk.red('Invalid path. Use format: account/collection'));
16
19
  process.exit(1);
17
20
  }
18
- const targetDir = directory || collectionSlug;
19
- // Check if directory exists
21
+ const targetDir = options.directory || collectionSlug;
20
22
  if (existsSync(targetDir)) {
21
23
  console.error(chalk.red(`Directory '${targetDir}' already exists`));
22
24
  process.exit(1);
23
25
  }
24
- const spinner = ora(`Cloning ${chalk.cyan(path)}...`).start();
26
+ const spinner = ora('Fetching collection...').start();
25
27
  // Get collection by slug
26
- const collectionResponse = await api.getCollectionBySlug(accountSlug, collectionSlug);
27
- if (collectionResponse.error || !collectionResponse.data) {
28
+ const collResponse = await api.getCollectionBySlug(accountSlug, collectionSlug);
29
+ if (collResponse.error || !collResponse.data) {
28
30
  spinner.fail('Collection not found');
29
- console.error(chalk.red(collectionResponse.error?.message || 'Collection not found'));
31
+ console.error(chalk.red(collResponse.error?.message || 'Collection not found'));
30
32
  process.exit(1);
31
33
  }
32
- const collection = collectionResponse.data;
33
- // Get collection files
34
+ const collection = collResponse.data;
34
35
  spinner.text = 'Fetching files...';
36
+ // Get collection files
35
37
  const filesResponse = await api.getCollectionFiles(collection.id);
36
38
  if (filesResponse.error || !filesResponse.data) {
37
39
  spinner.fail('Failed to fetch files');
@@ -39,48 +41,47 @@ export const cloneCommand = new Command('clone')
39
41
  process.exit(1);
40
42
  }
41
43
  const { files, commitSha, branch } = filesResponse.data;
44
+ spinner.text = 'Creating workspace...';
42
45
  // Create directory structure
43
- spinner.text = 'Writing files...';
44
46
  mkdirSync(targetDir, { recursive: true });
45
- // Write each file
46
- const fileIndex = {};
47
- const now = new Date().toISOString();
47
+ mkdirSync(join(targetDir, '.skillsdojo'), { recursive: true });
48
+ // Write files
49
+ const indexFiles = {};
48
50
  for (const file of files) {
49
51
  const filePath = join(targetDir, file.path);
50
- const fileDir = dirname(filePath);
51
- // Create directory if needed
52
- if (!existsSync(fileDir)) {
52
+ const fileDir = join(targetDir, file.path.split('/').slice(0, -1).join('/'));
53
+ if (fileDir !== targetDir) {
53
54
  mkdirSync(fileDir, { recursive: true });
54
55
  }
55
- // Write file
56
- writeFileSync(filePath, file.content, 'utf-8');
57
- // Track in index
58
- fileIndex[file.path] = {
56
+ writeFileSync(filePath, file.content);
57
+ indexFiles[file.path] = {
59
58
  sha: file.sha,
60
- mtime: now,
59
+ mtime: new Date().toISOString(),
61
60
  };
62
61
  }
63
62
  // Save workspace config
64
- saveWorkspaceConfig(targetDir, {
63
+ const config = {
65
64
  remote: {
66
- url: getApiUrl(),
65
+ url: `https://skillsdojo.ai/${accountSlug}/${collectionSlug}`,
67
66
  account: accountSlug,
68
67
  collection: collectionSlug,
69
68
  collectionId: collection.id,
70
69
  },
71
- branch,
72
- lastSync: now,
73
- });
74
- // Save file index
75
- saveWorkspaceIndex(targetDir, {
70
+ branch: branch || options.branch,
71
+ lastSync: new Date().toISOString(),
72
+ };
73
+ saveWorkspaceConfig(targetDir, config);
74
+ // Save index
75
+ const index = {
76
76
  commitSha,
77
- files: fileIndex,
78
- });
79
- spinner.succeed(`Cloned ${chalk.green(path)} into ${chalk.cyan(targetDir)}`);
80
- console.log(chalk.gray(`\n ${files.length} files`));
81
- console.log(chalk.gray(` Branch: ${branch}`));
82
- console.log(chalk.gray(` Commit: ${commitSha.substring(0, 7)}`));
77
+ files: indexFiles,
78
+ };
79
+ saveWorkspaceIndex(targetDir, index);
80
+ spinner.succeed(`Cloned ${chalk.green(collectionPath)} to ${chalk.cyan(targetDir)}`);
81
+ console.log();
82
+ console.log(chalk.gray(` Branch: ${branch || options.branch}`));
83
+ console.log(chalk.gray(` Files: ${files.length}`));
83
84
  console.log();
84
- console.log(`cd ${targetDir}`);
85
+ console.log(`cd ${targetDir} to start working`);
85
86
  });
86
87
  //# sourceMappingURL=clone.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEtF,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,6CAA6C,CAAC;KAC1D,QAAQ,CAAC,QAAQ,EAAE,sCAAsC,CAAC;KAC1D,QAAQ,CAAC,aAAa,EAAE,6CAA6C,CAAC;KACtE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;IAChC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEtD,IAAI,CAAC,WAAW,IAAI,CAAC,cAAc,EAAE,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,SAAS,IAAI,cAAc,CAAC;IAE9C,4BAA4B;IAC5B,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,SAAS,kBAAkB,CAAC,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAE9D,yBAAyB;IACzB,MAAM,kBAAkB,GAAG,MAAM,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAEtF,IAAI,kBAAkB,CAAC,KAAK,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,IAAI,sBAAsB,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,kBAAkB,CAAC,IAAI,CAAC;IAE3C,uBAAuB;IACvB,OAAO,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACnC,MAAM,aAAa,GAAG,MAAM,GAAG,CAAC,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAElE,IAAI,aAAa,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,IAAI,uBAAuB,CAAC,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC;IAExD,6BAA6B;IAC7B,OAAO,CAAC,IAAI,GAAG,kBAAkB,CAAC;IAClC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,kBAAkB;IAClB,MAAM,SAAS,GAAmD,EAAE,CAAC;IACrE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAElC,6BAA6B;QAC7B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;QAED,aAAa;QACb,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE/C,iBAAiB;QACjB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YACrB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,GAAG;SACX,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,mBAAmB,CAAC,SAAS,EAAE;QAC7B,MAAM,EAAE;YACN,GAAG,EAAE,SAAS,EAAE;YAChB,OAAO,EAAE,WAAW;YACpB,UAAU,EAAE,cAAc;YAC1B,YAAY,EAAE,UAAU,CAAC,EAAE;SAC5B;QACD,MAAM;QACN,QAAQ,EAAE,GAAG;KACd,CAAC,CAAC;IAEH,kBAAkB;IAClB,kBAAkB,CAAC,SAAS,EAAE;QAC5B,SAAS;QACT,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,OAAO,CAAC,OAAO,CAAC,UAAU,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/commands/clone.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const downloadCommand: Command;
3
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/commands/download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,eAAe,SAgKxB,CAAC"}
@@ -0,0 +1,145 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import inquirer from 'inquirer';
5
+ import { existsSync } from 'fs';
6
+ import { dirname } from 'path';
7
+ import { mkdir } from 'fs/promises';
8
+ import { api } from '../lib/api.js';
9
+ import { requireAuth } from '../lib/auth.js';
10
+ import { findWorkspaceRoot, getWorkspaceConfig } from '../lib/config.js';
11
+ export const downloadCommand = new Command('download')
12
+ .description('Download a collection or skills as a zip file')
13
+ .argument('[collection]', 'Collection to download (account/collection)')
14
+ .option('-o, --output <path>', 'Output file path')
15
+ .option('-s, --skills <paths>', 'Comma-separated skill paths to download')
16
+ .option('-b, --branch <name>', 'Branch to download from', 'main')
17
+ .option('--overwrite', 'Overwrite existing file without confirmation')
18
+ .option('--json', 'Output as JSON')
19
+ .action(async (collection, options) => {
20
+ requireAuth();
21
+ let collectionId;
22
+ let collectionPath;
23
+ let outputPath;
24
+ // Determine collection (from arg or workspace)
25
+ if (collection) {
26
+ const [accountSlug, collectionSlug] = collection.split('/');
27
+ if (!accountSlug || !collectionSlug) {
28
+ console.error(chalk.red('Invalid collection path. Use format: account/collection'));
29
+ process.exit(1);
30
+ }
31
+ // Get collection ID from API
32
+ const response = await api.getCollectionBySlug(accountSlug, collectionSlug);
33
+ if (response.error || !response.data) {
34
+ console.error(chalk.red(response.error?.message || 'Collection not found'));
35
+ process.exit(1);
36
+ }
37
+ collectionId = response.data.id;
38
+ collectionPath = collection;
39
+ // Default output path
40
+ outputPath = options.output || `./${collectionSlug}.zip`;
41
+ }
42
+ else {
43
+ // Use current workspace
44
+ const workspaceRoot = findWorkspaceRoot();
45
+ if (!workspaceRoot) {
46
+ console.error(chalk.red('No collection specified and not in a workspace'));
47
+ console.error(chalk.gray('Usage: sdojo download <account/collection>'));
48
+ process.exit(1);
49
+ }
50
+ const config = getWorkspaceConfig(workspaceRoot);
51
+ if (!config) {
52
+ console.error(chalk.red('Invalid workspace configuration'));
53
+ process.exit(1);
54
+ }
55
+ collectionId = config.remote.collectionId;
56
+ collectionPath = `${config.remote.account}/${config.remote.collection}`;
57
+ // Default output path
58
+ outputPath = options.output || `./${config.remote.collection}.zip`;
59
+ }
60
+ // Check if output file exists
61
+ if (existsSync(outputPath) && !options.overwrite) {
62
+ const { overwrite } = await inquirer.prompt([
63
+ {
64
+ type: 'confirm',
65
+ name: 'overwrite',
66
+ message: `File ${outputPath} already exists. Overwrite?`,
67
+ default: false,
68
+ },
69
+ ]);
70
+ if (!overwrite) {
71
+ console.log(chalk.yellow('Download cancelled'));
72
+ return;
73
+ }
74
+ }
75
+ const spinner = ora('Requesting download token...').start();
76
+ // Parse skill paths if provided
77
+ const skillPaths = options.skills
78
+ ? options.skills.split(',').map((s) => s.trim())
79
+ : undefined;
80
+ // Request download token
81
+ let tokenResponse;
82
+ try {
83
+ if (skillPaths && skillPaths.length > 0) {
84
+ tokenResponse = await api.requestSkillsDownloadToken(collectionId, {
85
+ skillPaths,
86
+ branch: options.branch,
87
+ });
88
+ }
89
+ else {
90
+ tokenResponse = await api.requestDownloadToken(collectionId, {
91
+ branch: options.branch,
92
+ });
93
+ }
94
+ if (tokenResponse.error || !tokenResponse.data) {
95
+ spinner.fail('Failed to request download');
96
+ console.error(chalk.red(tokenResponse.error?.message || 'Unknown error'));
97
+ process.exit(1);
98
+ }
99
+ }
100
+ catch (error) {
101
+ spinner.fail('Failed to request download');
102
+ console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
103
+ process.exit(1);
104
+ }
105
+ const { downloadToken, expiresAt } = tokenResponse.data;
106
+ const estimatedSizeMB = 'estimatedSizeMB' in tokenResponse.data ? tokenResponse.data.estimatedSizeMB : undefined;
107
+ spinner.text = `Downloading ${collectionPath}...`;
108
+ if (estimatedSizeMB) {
109
+ spinner.text += ` (estimated ${estimatedSizeMB}MB)`;
110
+ }
111
+ // Download the zip file
112
+ try {
113
+ // Ensure output directory exists
114
+ const outputDir = dirname(outputPath);
115
+ if (outputDir !== '.' && outputDir !== '') {
116
+ await mkdir(outputDir, { recursive: true });
117
+ }
118
+ await api.downloadZip(collectionId, downloadToken, outputPath);
119
+ spinner.succeed(`Downloaded to ${chalk.cyan(outputPath)}`);
120
+ if (!options.json) {
121
+ console.log();
122
+ console.log(chalk.gray(`Collection: ${collectionPath}`));
123
+ if (skillPaths) {
124
+ console.log(chalk.gray(`Skills: ${skillPaths.join(', ')}`));
125
+ }
126
+ console.log(chalk.gray(`Branch: ${options.branch}`));
127
+ console.log(chalk.gray(`Token expires: ${new Date(expiresAt).toLocaleString()}`));
128
+ }
129
+ else {
130
+ console.log(JSON.stringify({
131
+ success: true,
132
+ outputPath,
133
+ collection: collectionPath,
134
+ skills: skillPaths,
135
+ branch: options.branch,
136
+ }, null, 2));
137
+ }
138
+ }
139
+ catch (error) {
140
+ spinner.fail('Download failed');
141
+ console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
142
+ process.exit(1);
143
+ }
144
+ });
145
+ //# sourceMappingURL=download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/commands/download.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const initCommand: Command;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,WAAW,SA6JpB,CAAC"}