devskill 2.0.5 → 2.0.6
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/landing/app/[locale]/page.tsx +68 -2
- package/landing/messages/en.json +12 -2
- package/landing/messages/vi.json +13 -3
- package/meta.ts +9 -0
- package/package.json +5 -1
- package/scripts/cli.ts +121 -37
|
@@ -76,10 +76,10 @@ export default function LandingPage() {
|
|
|
76
76
|
<h1 className="text-6xl md:text-8xl font-extrabold mb-8 tracking-tight bg-clip-text text-transparent bg-gradient-to-br from-white via-zinc-200 to-zinc-500 pb-2">
|
|
77
77
|
{t('title')}
|
|
78
78
|
</h1>
|
|
79
|
-
<p className="text-xl md:text-2xl text-zinc-300 max-w-
|
|
79
|
+
<p className="text-xl md:text-2xl text-zinc-300 max-w-5xl mx-auto mb-12 leading-relaxed text-balance font-light">
|
|
80
80
|
{t('subtitle')}
|
|
81
81
|
</p>
|
|
82
|
-
<p className="text-lg text-zinc-400 max-w-
|
|
82
|
+
<p className="text-lg text-zinc-400 max-w-4xl mx-auto mb-12 leading-relaxed text-balance">
|
|
83
83
|
{h('description')}
|
|
84
84
|
</p>
|
|
85
85
|
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 w-full max-w-md mx-auto sm:max-w-none">
|
|
@@ -270,6 +270,72 @@ export default function LandingPage() {
|
|
|
270
270
|
</Card>
|
|
271
271
|
</div>
|
|
272
272
|
</section>
|
|
273
|
+
|
|
274
|
+
{/* Architecture Section */}
|
|
275
|
+
<section id="architecture" className="container mx-auto px-4 mb-40 relative z-10">
|
|
276
|
+
<div className="text-center mb-16">
|
|
277
|
+
<h2 className="text-4xl md:text-5xl font-extrabold mb-6 tracking-tight text-white">{t('architecture_title')}</h2>
|
|
278
|
+
<div className="w-24 h-1.5 bg-gradient-to-r from-cyan-400 to-rose-500 mx-auto rounded-full mb-6" />
|
|
279
|
+
<p className="text-xl text-zinc-400 max-w-3xl mx-auto leading-relaxed">{t('architecture_desc')}</p>
|
|
280
|
+
</div>
|
|
281
|
+
|
|
282
|
+
<div className="grid md:grid-cols-2 gap-8 max-w-5xl mx-auto">
|
|
283
|
+
<Card className="bg-zinc-900/60 border-cyan-400/20 backdrop-blur-xl hover:bg-zinc-900/80 hover:border-cyan-400/50 hover:-translate-y-2 hover:shadow-2xl hover:shadow-cyan-400/20 transition-all duration-300 group overflow-hidden relative">
|
|
284
|
+
<div className="absolute top-0 right-0 p-32 bg-cyan-400/5 rounded-full blur-[80px] -mr-16 -mt-16 transition-opacity opacity-0 group-hover:opacity-100" />
|
|
285
|
+
<CardHeader className="relative z-10">
|
|
286
|
+
<div className="w-14 h-14 rounded-2xl bg-cyan-400/10 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-500 border border-cyan-400/20">
|
|
287
|
+
<Database className="w-7 h-7 text-cyan-400" />
|
|
288
|
+
</div>
|
|
289
|
+
<CardTitle className="text-2xl text-white font-bold tracking-tight">{t('sources_title')}</CardTitle>
|
|
290
|
+
</CardHeader>
|
|
291
|
+
<CardContent className="relative z-10">
|
|
292
|
+
<p className="text-zinc-300 leading-relaxed text-base">{t('sources_desc')}</p>
|
|
293
|
+
</CardContent>
|
|
294
|
+
</Card>
|
|
295
|
+
|
|
296
|
+
<Card className="bg-zinc-900/60 border-rose-500/20 backdrop-blur-xl hover:bg-zinc-900/80 hover:border-rose-500/50 hover:-translate-y-2 hover:shadow-2xl hover:shadow-rose-500/20 transition-all duration-300 group overflow-hidden relative">
|
|
297
|
+
<div className="absolute top-0 right-0 p-32 bg-rose-500/5 rounded-full blur-[80px] -mr-16 -mt-16 transition-opacity opacity-0 group-hover:opacity-100" />
|
|
298
|
+
<CardHeader className="relative z-10">
|
|
299
|
+
<div className="w-14 h-14 rounded-2xl bg-rose-500/10 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-500 border border-rose-500/20">
|
|
300
|
+
<Boxes className="w-7 h-7 text-rose-500" />
|
|
301
|
+
</div>
|
|
302
|
+
<CardTitle className="text-2xl text-white font-bold tracking-tight">{t('vendor_title')}</CardTitle>
|
|
303
|
+
</CardHeader>
|
|
304
|
+
<CardContent className="relative z-10">
|
|
305
|
+
<p className="text-zinc-300 leading-relaxed text-base">{t('vendor_desc')}</p>
|
|
306
|
+
</CardContent>
|
|
307
|
+
</Card>
|
|
308
|
+
</div>
|
|
309
|
+
</section>
|
|
310
|
+
|
|
311
|
+
{/* Contribute Section */}
|
|
312
|
+
<section id="contribute" className="container mx-auto px-4 mb-40 text-center relative z-10">
|
|
313
|
+
<div className="max-w-4xl mx-auto bg-gradient-to-br from-zinc-900/80 to-zinc-950 border border-white/10 p-10 md:p-14 rounded-3xl shadow-2xl relative overflow-hidden group">
|
|
314
|
+
<div className="absolute top-0 right-0 p-32 bg-rose-500/10 rounded-full blur-[100px] -mr-16 -mt-16 pointer-events-none" />
|
|
315
|
+
<div className="absolute bottom-0 left-0 p-32 bg-cyan-400/10 rounded-full blur-[100px] -ml-16 -mb-16 pointer-events-none" />
|
|
316
|
+
|
|
317
|
+
<h2 className="text-3xl md:text-5xl font-extrabold mb-6 tracking-tight text-white">{t('contribute_title')}</h2>
|
|
318
|
+
<p className="text-lg md:text-xl text-zinc-300 max-w-3xl mx-auto mb-10 leading-relaxed font-light">
|
|
319
|
+
{t('contribute_desc')}
|
|
320
|
+
</p>
|
|
321
|
+
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
|
|
322
|
+
<a
|
|
323
|
+
href="https://github.com/vuluu2k/skills/issues"
|
|
324
|
+
target="_blank"
|
|
325
|
+
className="px-8 py-4 rounded-xl font-bold bg-white text-zinc-950 hover:bg-zinc-200 transition-colors shadow-lg shadow-white/10"
|
|
326
|
+
>
|
|
327
|
+
{t('contribute_cta_issue')}
|
|
328
|
+
</a>
|
|
329
|
+
<a
|
|
330
|
+
href="https://github.com/vuluu2k/skills"
|
|
331
|
+
target="_blank"
|
|
332
|
+
className="px-8 py-4 rounded-xl font-bold bg-zinc-800 text-white hover:bg-zinc-700 border border-white/10 transition-colors"
|
|
333
|
+
>
|
|
334
|
+
{t('contribute_cta_build')}
|
|
335
|
+
</a>
|
|
336
|
+
</div>
|
|
337
|
+
</div>
|
|
338
|
+
</section>
|
|
273
339
|
</main>
|
|
274
340
|
|
|
275
341
|
<footer className="border-t border-white/10 py-12 bg-zinc-950/80 backdrop-blur-sm">
|
package/landing/messages/en.json
CHANGED
|
@@ -5,9 +5,19 @@
|
|
|
5
5
|
"problem": "The Problem",
|
|
6
6
|
"solution": "The Solution",
|
|
7
7
|
"why_devskill": "The power of devskill",
|
|
8
|
-
"installation": "
|
|
8
|
+
"installation": "Installation & Quick Start",
|
|
9
9
|
"collections": "Skill Collections",
|
|
10
|
-
"footer": "
|
|
10
|
+
"footer": "© 2026 devskill. Empower your AI assistants.",
|
|
11
|
+
"contribute_title": "Build & Contribute",
|
|
12
|
+
"contribute_desc": "Does your team have unique coding standards? You can easily build a completely customized AI brain! If you have any awesome frameworks or best-practices you'd like to share, create an Issue on GitHub so we can add it to devskill.",
|
|
13
|
+
"contribute_cta_issue": "💡 Suggest a Skill",
|
|
14
|
+
"contribute_cta_build": "🛠️ Build Your Own",
|
|
15
|
+
"architecture_title": "Smart Directory Architecture",
|
|
16
|
+
"architecture_desc": "More than just a CLI, devskill provides a clearly stratified Knowledge Base management pipeline.",
|
|
17
|
+
"sources_title": "The Root (sources/)",
|
|
18
|
+
"sources_desc": "The raw data layer. Stores official documentation, template repos, and guidelines (often tracked as git submodules). AI reads this to generate your SKILL.md rules.",
|
|
19
|
+
"vendor_title": "Submodules (vendor/)",
|
|
20
|
+
"vendor_desc": "Your external dependency layer. Automatically syncs community or third-party high-quality skills into your project. Keep them fresh with a single 'npm start sync'."
|
|
11
21
|
},
|
|
12
22
|
"Hero": {
|
|
13
23
|
"badge": "🚀 NEW: devskill v2.0",
|
package/landing/messages/vi.json
CHANGED
|
@@ -5,9 +5,19 @@
|
|
|
5
5
|
"problem": "Vấn đề",
|
|
6
6
|
"solution": "Giải pháp",
|
|
7
7
|
"why_devskill": "Sức mạnh thực sự của devskill",
|
|
8
|
-
"installation": "Cài đặt
|
|
9
|
-
"collections": "
|
|
10
|
-
"footer": "
|
|
8
|
+
"installation": "Cài đặt & Trải nghiệm",
|
|
9
|
+
"collections": "Bộ sưu tập Skills",
|
|
10
|
+
"footer": "© 2026 devskill. Xây dựng bộ não mạnh mẽ nhất cho AI của bạn.",
|
|
11
|
+
"contribute_title": "Tự Xây Dựng & Đóng Góp",
|
|
12
|
+
"contribute_desc": "Đội ngũ của bạn có quy chuẩn code riêng? Đừng lo, bạn có thể tự build bộ não AI chuyên biệt cho team! Nếu bạn biết một framework hay best-practices nào đỉnh cao, hãy tạo Issue trên GitHub để mình thêm vào devskill nhé.",
|
|
13
|
+
"contribute_cta_issue": "💡 Gợi ý Skills (Tạo Issue)",
|
|
14
|
+
"contribute_cta_build": "🛠️ Tự Build Skills",
|
|
15
|
+
"architecture_title": "Cấu trúc Thư mục Thông minh",
|
|
16
|
+
"architecture_desc": "Không chỉ là một CLI, devskill cung cấp vòng đời quản lý tri thức (Knowledge Base) phân tầng rõ rệt.",
|
|
17
|
+
"sources_title": "Nguồn gốc (sources/)",
|
|
18
|
+
"sources_desc": "Nơi chứa tài liệu gốc, mã nguồn mẫu, official documentation (thường track dưới dạng git submodules). AI sẽ đọc và đọc hiểu tự động để trích xuất các quy chuẩn ra file SKILL.md.",
|
|
19
|
+
"vendor_title": "Cộng đồng (vendor/)",
|
|
20
|
+
"vendor_desc": "Kho lưu trữ các skill chất lượng cao được chia sẻ từ cộng đồng hoặc tổ chức khác. Chỉ cần 1 lệnh 'npm start sync' để cập nhật liên tục mọi thay đổi về máy!"
|
|
11
21
|
},
|
|
12
22
|
"Hero": {
|
|
13
23
|
"badge": "🚀 MỚI: devskill v2.0",
|
package/meta.ts
CHANGED
|
@@ -80,6 +80,15 @@ export const vendors: Record<string, VendorSkillMeta> = {
|
|
|
80
80
|
turborepo: 'turborepo',
|
|
81
81
|
},
|
|
82
82
|
},
|
|
83
|
+
'next-skills': {
|
|
84
|
+
official: true,
|
|
85
|
+
source: 'https://github.com/vercel-labs/next-skills',
|
|
86
|
+
skills: {
|
|
87
|
+
'next-best-practices': 'next-best-practices',
|
|
88
|
+
'next-cache-components': 'next-cache-components',
|
|
89
|
+
'next-upgrade': 'next-upgrade',
|
|
90
|
+
},
|
|
91
|
+
}
|
|
83
92
|
}
|
|
84
93
|
|
|
85
94
|
export const manual = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devskill",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Equip Cursor, Windsurf, Cline, Antigravity, Claude Code, Codex, GitHub Copilot and other AI Agents with expert programming superpowers via a single interactive prompt.",
|
|
5
5
|
"homepage": "https://vskill.vercel.app",
|
|
6
6
|
"repository": {
|
|
@@ -18,10 +18,14 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@clack/prompts": "^1.1.0",
|
|
21
|
+
"@inquirer/prompts": "^8.3.2",
|
|
22
|
+
"enquirer": "^2.4.1",
|
|
23
|
+
"prompts": "^2.4.2",
|
|
21
24
|
"tsx": "^4.0.0"
|
|
22
25
|
},
|
|
23
26
|
"devDependencies": {
|
|
24
27
|
"@types/node": "^20.0.0",
|
|
28
|
+
"@types/prompts": "^2.4.9",
|
|
25
29
|
"typescript": "^5.5.0"
|
|
26
30
|
}
|
|
27
31
|
}
|
package/scripts/cli.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { dirname, join } from 'node:path'
|
|
|
4
4
|
import process from 'node:process'
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
6
6
|
import * as p from '@clack/prompts'
|
|
7
|
+
import prompts from 'prompts'
|
|
7
8
|
import { collections, manual, submodules, vendors } from '../meta.ts'
|
|
8
9
|
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
@@ -364,7 +365,7 @@ async function cleanup(skipPrompt = false) {
|
|
|
364
365
|
}
|
|
365
366
|
}
|
|
366
367
|
|
|
367
|
-
async function installSkills() {
|
|
368
|
+
async function installSkills(targetCollectionNames: string[] = []) {
|
|
368
369
|
const spinner = p.spinner()
|
|
369
370
|
|
|
370
371
|
const allCollections: Record<string, string[]> = { ...collections }
|
|
@@ -378,23 +379,33 @@ async function installSkills() {
|
|
|
378
379
|
return
|
|
379
380
|
}
|
|
380
381
|
|
|
381
|
-
|
|
382
|
-
message: 'Select collections to install (Space to select, Enter to confirm)',
|
|
383
|
-
options: Object.keys(allCollections).map(name => ({
|
|
384
|
-
value: name,
|
|
385
|
-
label: name,
|
|
386
|
-
hint: `${allCollections[name].length} skills`
|
|
387
|
-
}))
|
|
388
|
-
})
|
|
382
|
+
let selectedCollectionNames: string[] = []
|
|
389
383
|
|
|
390
|
-
if (
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
384
|
+
if (targetCollectionNames.length > 0) {
|
|
385
|
+
const invalid = targetCollectionNames.filter(name => !allCollections[name])
|
|
386
|
+
if (invalid.length > 0) {
|
|
387
|
+
p.log.error(`Collections not found: ${invalid.join(', ')}`)
|
|
388
|
+
return
|
|
389
|
+
}
|
|
390
|
+
selectedCollectionNames = targetCollectionNames
|
|
391
|
+
} else {
|
|
392
|
+
const response = await prompts({
|
|
393
|
+
type: 'autocompleteMultiselect',
|
|
394
|
+
name: 'selected',
|
|
395
|
+
message: 'Search and select collections to install (Space to select, Enter to confirm)',
|
|
396
|
+
choices: Object.keys(allCollections).map(name => ({
|
|
397
|
+
title: name,
|
|
398
|
+
value: name,
|
|
399
|
+
description: `${allCollections[name].length} skills`
|
|
400
|
+
}))
|
|
401
|
+
})
|
|
394
402
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
403
|
+
if (!response.selected || response.selected.length === 0) {
|
|
404
|
+
p.log.warn('No collections selected (or canceled)')
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
selectedCollectionNames = response.selected
|
|
398
409
|
}
|
|
399
410
|
|
|
400
411
|
const targetProject = await p.text({
|
|
@@ -492,7 +503,7 @@ async function installSkills() {
|
|
|
492
503
|
spinner.stop(`Installed ${successCount}/${selectedSkills.length} skills to target project`)
|
|
493
504
|
}
|
|
494
505
|
|
|
495
|
-
async function installSpecificSkills() {
|
|
506
|
+
async function installSpecificSkills(targetSkillNames: string[] = []) {
|
|
496
507
|
const spinner = p.spinner()
|
|
497
508
|
|
|
498
509
|
const allSkills = getExistingSkillNames()
|
|
@@ -502,22 +513,32 @@ async function installSpecificSkills() {
|
|
|
502
513
|
return
|
|
503
514
|
}
|
|
504
515
|
|
|
505
|
-
|
|
506
|
-
message: 'Select specific skills to install (Space to select, Enter to confirm)',
|
|
507
|
-
options: allSkills.map(name => ({
|
|
508
|
-
value: name,
|
|
509
|
-
label: name
|
|
510
|
-
}))
|
|
511
|
-
})
|
|
516
|
+
let selectedSkills: string[] = []
|
|
512
517
|
|
|
513
|
-
if (
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
518
|
+
if (targetSkillNames.length > 0) {
|
|
519
|
+
const invalid = targetSkillNames.filter(name => !allSkills.includes(name))
|
|
520
|
+
if (invalid.length > 0) {
|
|
521
|
+
p.log.error(`Skills not found: ${invalid.join(', ')}`)
|
|
522
|
+
return
|
|
523
|
+
}
|
|
524
|
+
selectedSkills = targetSkillNames
|
|
525
|
+
} else {
|
|
526
|
+
const response = await prompts({
|
|
527
|
+
type: 'autocompleteMultiselect',
|
|
528
|
+
name: 'selected',
|
|
529
|
+
message: 'Search and select individual skills to install (Space to select, Enter to confirm)',
|
|
530
|
+
choices: allSkills.map(name => ({
|
|
531
|
+
title: name,
|
|
532
|
+
value: name
|
|
533
|
+
}))
|
|
534
|
+
})
|
|
517
535
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
536
|
+
if (!response.selected || response.selected.length === 0) {
|
|
537
|
+
p.log.warn('No skills selected (or canceled)')
|
|
538
|
+
return
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
selectedSkills = response.selected
|
|
521
542
|
}
|
|
522
543
|
|
|
523
544
|
const targetProject = await p.text({
|
|
@@ -612,10 +633,67 @@ async function installSpecificSkills() {
|
|
|
612
633
|
spinner.stop(`Installed ${successCount}/${selectedSkills.length} skills to target project`)
|
|
613
634
|
}
|
|
614
635
|
|
|
636
|
+
async function findSkills(query?: string) {
|
|
637
|
+
const allSkills = getExistingSkillNames()
|
|
638
|
+
p.intro(`Search results for ${query ? `"${query}"` : 'all'}`)
|
|
639
|
+
|
|
640
|
+
const allCollections: Record<string, string[]> = { ...collections }
|
|
641
|
+
for (const [vendorName, config] of Object.entries(vendors)) {
|
|
642
|
+
const vendorConfig = config as VendorConfig
|
|
643
|
+
allCollections[vendorName] = Object.values(vendorConfig.skills)
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
let q = ''
|
|
647
|
+
if (!query) {
|
|
648
|
+
const userInput = await p.text({
|
|
649
|
+
message: 'Enter keyword to search (leave empty to list all):',
|
|
650
|
+
placeholder: 'e.g. vue'
|
|
651
|
+
})
|
|
652
|
+
|
|
653
|
+
if (p.isCancel(userInput)) {
|
|
654
|
+
p.cancel('Cancelled')
|
|
655
|
+
return
|
|
656
|
+
}
|
|
657
|
+
q = (userInput as string).toLowerCase()
|
|
658
|
+
} else {
|
|
659
|
+
q = query.toLowerCase()
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const matchedCollections = Object.keys(allCollections).filter(c => c.toLowerCase().includes(q))
|
|
663
|
+
if (matchedCollections.length > 0) {
|
|
664
|
+
p.log.success('📚 Collections found:')
|
|
665
|
+
for (const c of matchedCollections) {
|
|
666
|
+
p.log.message(` - ${c} (${allCollections[c].length} skills) -> \`npx devskill install ${c}\``)
|
|
667
|
+
}
|
|
668
|
+
} else if (q) {
|
|
669
|
+
p.log.warn('No collections found matching query')
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
const matchedSkills = allSkills.filter(s => s.toLowerCase().includes(q))
|
|
673
|
+
if (matchedSkills.length > 0) {
|
|
674
|
+
p.log.success('🛠️ Individual Skills found:')
|
|
675
|
+
for (const s of matchedSkills) {
|
|
676
|
+
p.log.message(` - ${s} -> \`npx devskill add ${s}\``)
|
|
677
|
+
}
|
|
678
|
+
} else if (q) {
|
|
679
|
+
p.log.warn('No individual skills found matching query')
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
615
683
|
async function main() {
|
|
616
684
|
const args = process.argv.slice(2)
|
|
617
685
|
const skipPrompt = args.includes('-y') || args.includes('--yes')
|
|
618
|
-
|
|
686
|
+
|
|
687
|
+
const positionalArgs = args.filter(arg => !arg.startsWith('-'))
|
|
688
|
+
const command = positionalArgs[0]
|
|
689
|
+
const targetNames = positionalArgs.slice(1)
|
|
690
|
+
const targetName = targetNames[0] // for finding
|
|
691
|
+
|
|
692
|
+
if (command === 'find') {
|
|
693
|
+
await findSkills(targetName)
|
|
694
|
+
p.outro('Done')
|
|
695
|
+
return
|
|
696
|
+
}
|
|
619
697
|
|
|
620
698
|
if (command === 'init') {
|
|
621
699
|
p.intro('Skills Manager - Init')
|
|
@@ -646,22 +724,24 @@ async function main() {
|
|
|
646
724
|
}
|
|
647
725
|
|
|
648
726
|
if (command === 'install') {
|
|
649
|
-
|
|
650
|
-
|
|
727
|
+
const namesJoined = targetNames.length > 0 ? ` (${targetNames.join(', ')})` : ''
|
|
728
|
+
p.intro(`Skills Manager - Install Groups${namesJoined}`)
|
|
729
|
+
await installSkills(targetNames)
|
|
651
730
|
p.outro('Done')
|
|
652
731
|
return
|
|
653
732
|
}
|
|
654
733
|
|
|
655
734
|
if (command === 'add') {
|
|
656
|
-
|
|
657
|
-
|
|
735
|
+
const namesJoined = targetNames.length > 0 ? ` (${targetNames.join(', ')})` : ''
|
|
736
|
+
p.intro(`Skills Manager - Add Specific Skills${namesJoined}`)
|
|
737
|
+
await installSpecificSkills(targetNames)
|
|
658
738
|
p.outro('Done')
|
|
659
739
|
return
|
|
660
740
|
}
|
|
661
741
|
|
|
662
742
|
if (skipPrompt) {
|
|
663
743
|
p.log.error('Command required when using -y flag')
|
|
664
|
-
p.log.info('Available commands: install, add, init, sync, check, cleanup')
|
|
744
|
+
p.log.info('Available commands: find, install, add, init, sync, check, cleanup')
|
|
665
745
|
process.exit(1)
|
|
666
746
|
}
|
|
667
747
|
|
|
@@ -672,6 +752,7 @@ async function main() {
|
|
|
672
752
|
options: [
|
|
673
753
|
{ value: 'install', label: 'Install collections', hint: 'Copy entire skill collections to a local project' },
|
|
674
754
|
{ value: 'add', label: 'Add specific skills', hint: 'Choose individual skills to add to your project' },
|
|
755
|
+
{ value: 'find', label: 'Find a skill or collection', hint: 'Search by keyword' },
|
|
675
756
|
{ value: 'sync', label: 'Sync submodules', hint: 'Pull latest and sync Type 2 skills' },
|
|
676
757
|
{ value: 'init', label: 'Init submodules', hint: 'Add new submodules from meta.ts' },
|
|
677
758
|
{ value: 'check', label: 'Check updates', hint: 'See available updates' },
|
|
@@ -691,6 +772,9 @@ async function main() {
|
|
|
691
772
|
case 'add':
|
|
692
773
|
await installSpecificSkills()
|
|
693
774
|
break
|
|
775
|
+
case 'find':
|
|
776
|
+
await findSkills()
|
|
777
|
+
break
|
|
694
778
|
case 'init':
|
|
695
779
|
await initSubmodules()
|
|
696
780
|
break
|