mdpush 1.1.1 → 1.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.
- package/package.json +1 -1
- package/src/commands/skill-command.js +40 -6
- package/src/index.js +3 -3
package/package.json
CHANGED
|
@@ -12,7 +12,9 @@ import { apiRequest } from '../lib/api-request.js'
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
// Mirrors the server's TEXT_UPLOAD_EXTENSIONS (upload-middleware.js)
|
|
15
|
-
|
|
15
|
+
// .html rides the server's dedicated artifact pipe (?contentType=html) —
|
|
16
|
+
// used by assets/preview.html + assets/slides.html (AUTHORING.md standard).
|
|
17
|
+
const SKILL_FILE_EXTENSIONS = new Set(['.md', '.txt', '.py', '.sh', '.js', '.mjs', '.cjs', '.ps1', '.json', '.yaml', '.yml', '.html'])
|
|
16
18
|
|
|
17
19
|
/** Recursive walk: relative POSIX paths, dotfiles + node_modules skipped. */
|
|
18
20
|
function walkSkillDir(root, rel = '') {
|
|
@@ -64,7 +66,10 @@ export async function skillPushCommand(dir, options) {
|
|
|
64
66
|
const formData = new FormData()
|
|
65
67
|
formData.append('files', new Blob([fs.readFileSync(path.join(root, relPath))]), path.basename(relPath))
|
|
66
68
|
const folder = path.dirname(relPath)
|
|
67
|
-
const
|
|
69
|
+
const params = new URLSearchParams()
|
|
70
|
+
if (folder && folder !== '.') params.set('folder', folder)
|
|
71
|
+
if (relPath.endsWith('.html')) params.set('contentType', 'html')
|
|
72
|
+
const query = params.size > 0 ? `?${params}` : ''
|
|
68
73
|
await apiRequest(`/api/projects/${project.slug}/upload${query}`, {
|
|
69
74
|
method: 'POST',
|
|
70
75
|
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
|
@@ -81,9 +86,37 @@ export async function skillPushCommand(dir, options) {
|
|
|
81
86
|
if (failed) process.exit(1)
|
|
82
87
|
}
|
|
83
88
|
|
|
84
|
-
/**
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Install published skills into ~/.claude/skills/<slug> (or --dest).
|
|
91
|
+
* Accepts several slugs (space or comma separated); each installs
|
|
92
|
+
* independently — one failure doesn't abort the rest (exit 1 at the end).
|
|
93
|
+
*/
|
|
94
|
+
export async function skillInstallCommand(slugs, options) {
|
|
95
|
+
const list = [...new Set(slugs.flatMap(s => s.split(',')).map(s => s.trim()).filter(Boolean))]
|
|
96
|
+
if (list.length > 1 && options.dest) {
|
|
97
|
+
console.log(chalk.red('--dest is ambiguous with multiple skills — install them one at a time.'))
|
|
98
|
+
process.exit(2)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const failedSlugs = []
|
|
102
|
+
for (const slug of list) {
|
|
103
|
+
try {
|
|
104
|
+
await installOneSkill(slug, options)
|
|
105
|
+
} catch (err) {
|
|
106
|
+
console.log(chalk.red(`✖ ${slug}: ${err.message}`))
|
|
107
|
+
failedSlugs.push(slug)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (list.length > 1) {
|
|
111
|
+
console.log(`\n${chalk.green(`${list.length - failedSlugs.length} skill(s) installed`)}${failedSlugs.length ? `, ${chalk.red(`${failedSlugs.length} failed (${failedSlugs.join(', ')})`)}` : ''}`)
|
|
112
|
+
}
|
|
113
|
+
if (failedSlugs.length) process.exit(1)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Install one skill. `?source=cli-install` marks a real install so the
|
|
117
|
+
* server bumps install_count (detail-page manifest fetches don't). */
|
|
118
|
+
async function installOneSkill(slug, options) {
|
|
119
|
+
const manifestRes = await apiRequest(`/api/skills/${slug}/manifest?source=cli-install`)
|
|
87
120
|
const manifest = await manifestRes.json()
|
|
88
121
|
|
|
89
122
|
const dest = path.resolve(options.dest || path.join(os.homedir(), '.claude', 'skills', slug))
|
|
@@ -110,7 +143,8 @@ export async function skillInstallCommand(slug, options) {
|
|
|
110
143
|
}
|
|
111
144
|
}
|
|
112
145
|
console.log(`\n${chalk.green(`${success} installed`)}${failed ? `, ${chalk.red(`${failed} failed`)}` : ''}`)
|
|
113
|
-
|
|
146
|
+
// Throw (not exit) so a batch install can continue with the next slug.
|
|
147
|
+
if (failed) throw new Error(`${failed} file(s) failed`)
|
|
114
148
|
}
|
|
115
149
|
|
|
116
150
|
/** List published skills. */
|
package/src/index.js
CHANGED
|
@@ -33,9 +33,9 @@ skill.command('push')
|
|
|
33
33
|
.action(skillPushCommand)
|
|
34
34
|
|
|
35
35
|
skill.command('install')
|
|
36
|
-
.description('Install
|
|
37
|
-
.argument('<
|
|
38
|
-
.option('-d, --dest <path>', 'Destination directory (
|
|
36
|
+
.description('Install published skills into ~/.claude/skills/<slug>')
|
|
37
|
+
.argument('<slugs...>', 'Skill slug(s) — space or comma separated (see: mdpush skill list)')
|
|
38
|
+
.option('-d, --dest <path>', 'Destination directory (single skill only)')
|
|
39
39
|
.action(skillInstallCommand)
|
|
40
40
|
|
|
41
41
|
skill.command('list')
|