@skillkit/cli 1.9.0 → 1.11.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/dist/index.js CHANGED
@@ -3391,7 +3391,10 @@ var RecommendCommand = class extends Command15 {
3391
3391
  ["Show detailed reasons", "$0 recommend --verbose"],
3392
3392
  ["Update skill index", "$0 recommend --update"],
3393
3393
  ["Search for skills by task", '$0 recommend --task "authentication"'],
3394
- ["Search for skills (alias)", '$0 recommend --search "testing"']
3394
+ ["Search for skills (alias)", '$0 recommend --search "testing"'],
3395
+ ["Hybrid search (vector + keyword)", '$0 recommend --search "auth" --hybrid'],
3396
+ ["Hybrid search with query expansion", '$0 recommend --search "auth" --hybrid --expand'],
3397
+ ["Build hybrid search index", "$0 recommend --build-index"]
3395
3398
  ]
3396
3399
  });
3397
3400
  // Limit number of results
@@ -3450,11 +3453,33 @@ var RecommendCommand = class extends Command15 {
3450
3453
  showPath = Option14.Boolean("--show-path", false, {
3451
3454
  description: "Show category path for each recommendation"
3452
3455
  });
3456
+ // Hybrid search mode
3457
+ hybrid = Option14.Boolean("--hybrid,-H", false, {
3458
+ description: "Use hybrid search (vector + keyword)"
3459
+ });
3460
+ // Query expansion
3461
+ expand = Option14.Boolean("--expand,-x", false, {
3462
+ description: "Enable query expansion (requires --hybrid)"
3463
+ });
3464
+ // Reranking
3465
+ rerank = Option14.Boolean("--rerank", false, {
3466
+ description: "Enable LLM reranking (requires --hybrid)"
3467
+ });
3468
+ // Build index
3469
+ buildIndex = Option14.Boolean("--build-index", false, {
3470
+ description: "Build/rebuild the hybrid search embedding index"
3471
+ });
3453
3472
  async execute() {
3454
3473
  const targetPath = resolve4(this.projectPath || process.cwd());
3455
3474
  if (this.update) {
3456
3475
  return await this.updateIndex();
3457
3476
  }
3477
+ if (this.buildIndex) {
3478
+ return await this.buildHybridIndex();
3479
+ }
3480
+ if ((this.expand || this.rerank) && !this.hybrid) {
3481
+ warn("--expand and --rerank require --hybrid flag. These options will be ignored.");
3482
+ }
3458
3483
  if (!this.quiet && !this.json) {
3459
3484
  header("Skill Recommendations");
3460
3485
  }
@@ -3478,6 +3503,9 @@ var RecommendCommand = class extends Command15 {
3478
3503
  engine.loadIndex(index);
3479
3504
  const searchQuery = this.search || this.task;
3480
3505
  if (searchQuery) {
3506
+ if (this.hybrid) {
3507
+ return await this.handleHybridSearch(engine, searchQuery);
3508
+ }
3481
3509
  return this.handleSearch(engine, searchQuery);
3482
3510
  }
3483
3511
  const result = engine.recommend(profile, {
@@ -3691,6 +3719,110 @@ var RecommendCommand = class extends Command15 {
3691
3719
  console.log(colors.muted("Install with: skillkit install <source>"));
3692
3720
  console.log(colors.muted("More details: skillkit recommend --explain --verbose"));
3693
3721
  }
3722
+ async handleHybridSearch(engine, query) {
3723
+ if (!this.quiet && !this.json) {
3724
+ header(`Hybrid Search: "${query}"`);
3725
+ }
3726
+ const s = !this.quiet && !this.json ? spinner2() : null;
3727
+ s?.start("Initializing hybrid search...");
3728
+ try {
3729
+ await engine.initHybridSearch();
3730
+ s?.message("Searching...");
3731
+ const results = await engine.hybridSearch({
3732
+ query,
3733
+ limit: this.limit ? parseInt(this.limit, 10) : 10,
3734
+ hybrid: true,
3735
+ enableExpansion: this.expand,
3736
+ enableReranking: this.rerank,
3737
+ filters: {
3738
+ minScore: this.minScore ? parseInt(this.minScore, 10) : void 0
3739
+ }
3740
+ });
3741
+ s?.stop(`Found ${results.length} results`);
3742
+ if (this.json) {
3743
+ console.log(JSON.stringify(results, null, 2));
3744
+ return 0;
3745
+ }
3746
+ if (results.length === 0) {
3747
+ warn(`No skills found matching "${query}"`);
3748
+ return 0;
3749
+ }
3750
+ console.log("");
3751
+ console.log(colors.bold(`Hybrid search results for "${query}" (${results.length} found):`));
3752
+ if (this.expand && results[0]?.expandedTerms?.length) {
3753
+ console.log(colors.muted(` Expanded: ${results[0].expandedTerms.join(", ")}`));
3754
+ }
3755
+ console.log("");
3756
+ for (const result of results) {
3757
+ let relevanceColor;
3758
+ if (result.relevance >= 70) {
3759
+ relevanceColor = colors.success;
3760
+ } else if (result.relevance >= 50) {
3761
+ relevanceColor = colors.warning;
3762
+ } else {
3763
+ relevanceColor = colors.muted;
3764
+ }
3765
+ const relevanceBar = progressBar(result.relevance, 100, 10);
3766
+ console.log(` ${relevanceColor(`${result.relevance}%`)} ${colors.dim(relevanceBar)} ${colors.bold(result.skill.name)}`);
3767
+ if (result.skill.description) {
3768
+ console.log(` ${colors.muted(truncate3(result.skill.description, 70))}`);
3769
+ }
3770
+ if (this.verbose) {
3771
+ const scores = [];
3772
+ if (typeof result.vectorSimilarity === "number") {
3773
+ scores.push(`vector: ${(result.vectorSimilarity * 100).toFixed(0)}%`);
3774
+ }
3775
+ if (typeof result.keywordScore === "number") {
3776
+ scores.push(`keyword: ${result.keywordScore.toFixed(0)}%`);
3777
+ }
3778
+ if (typeof result.rrfScore === "number") {
3779
+ scores.push(`rrf: ${result.rrfScore.toFixed(3)}`);
3780
+ }
3781
+ if (scores.length > 0) {
3782
+ console.log(` ${colors.dim("Scores:")} ${scores.join(" | ")}`);
3783
+ }
3784
+ }
3785
+ if (result.matchedTerms.length > 0) {
3786
+ console.log(` ${colors.dim("Matched:")} ${result.matchedTerms.join(", ")}`);
3787
+ }
3788
+ console.log("");
3789
+ }
3790
+ return 0;
3791
+ } catch (err) {
3792
+ s?.stop(colors.error("Hybrid search failed"));
3793
+ console.log(colors.muted(err instanceof Error ? err.message : String(err)));
3794
+ console.log(colors.muted("Falling back to standard search..."));
3795
+ return this.handleSearch(engine, query);
3796
+ }
3797
+ }
3798
+ async buildHybridIndex() {
3799
+ if (!this.quiet) {
3800
+ header("Build Hybrid Search Index");
3801
+ }
3802
+ const index = this.loadIndex();
3803
+ if (!index || index.skills.length === 0) {
3804
+ warn("No skill index found. Run --update first.");
3805
+ return 1;
3806
+ }
3807
+ const s = spinner2();
3808
+ s.start("Initializing...");
3809
+ try {
3810
+ const engine = new RecommendationEngine();
3811
+ engine.loadIndex(index);
3812
+ await engine.buildHybridIndex((progress) => {
3813
+ const percentage = Math.round(progress.current / progress.total * 100);
3814
+ s.message(`${progress.phase}: ${progress.message || ""} (${percentage}%)`);
3815
+ });
3816
+ s.stop(colors.success(`${symbols.success} Built hybrid index for ${index.skills.length} skills`));
3817
+ console.log(colors.muted(" Index stored in: ~/.skillkit/search.db"));
3818
+ console.log(colors.muted(" Use --hybrid flag for vector+keyword search\n"));
3819
+ return 0;
3820
+ } catch (err) {
3821
+ s.stop(colors.error("Failed to build hybrid index"));
3822
+ console.log(colors.muted(err instanceof Error ? err.message : String(err)));
3823
+ return 1;
3824
+ }
3825
+ }
3694
3826
  handleSearch(engine, query) {
3695
3827
  if (!this.quiet && !this.json) {
3696
3828
  header(`Search: "${query}"`);
@@ -5658,12 +5790,12 @@ ${learning.title}
5658
5790
  }
5659
5791
  const outputPath = this.output || `.skillkit/exports/${skillName}/SKILL.md`;
5660
5792
  const { dirname: dirname7 } = await import("path");
5661
- const { existsSync: existsSync21, mkdirSync: mkdirSync10, writeFileSync: writeFileSync11 } = await import("fs");
5793
+ const { existsSync: existsSync23, mkdirSync: mkdirSync11, writeFileSync: writeFileSync12 } = await import("fs");
5662
5794
  const outputDir = dirname7(outputPath);
5663
- if (!existsSync21(outputDir)) {
5664
- mkdirSync10(outputDir, { recursive: true });
5795
+ if (!existsSync23(outputDir)) {
5796
+ mkdirSync11(outputDir, { recursive: true });
5665
5797
  }
5666
- writeFileSync11(outputPath, skillContent, "utf-8");
5798
+ writeFileSync12(outputPath, skillContent, "utf-8");
5667
5799
  console.log(chalk18.green(`\u2713 Exported learning as skill: ${skillName}`));
5668
5800
  console.log(chalk18.gray(` Path: ${outputPath}`));
5669
5801
  return 0;
@@ -5678,10 +5810,10 @@ ${learning.title}
5678
5810
  console.log(chalk18.gray("Usage: skillkit memory import --input <path>"));
5679
5811
  return 1;
5680
5812
  }
5681
- const { existsSync: existsSync21, readFileSync: readFileSync11 } = await import("fs");
5682
- const { resolve: resolve21 } = await import("path");
5683
- const fullPath = resolve21(inputPath);
5684
- if (!existsSync21(fullPath)) {
5813
+ const { existsSync: existsSync23, readFileSync: readFileSync12 } = await import("fs");
5814
+ const { resolve: resolve23 } = await import("path");
5815
+ const fullPath = resolve23(inputPath);
5816
+ if (!existsSync23(fullPath)) {
5685
5817
  console.error(chalk18.red(`File not found: ${fullPath}`));
5686
5818
  return 1;
5687
5819
  }
@@ -5691,7 +5823,7 @@ ${learning.title}
5691
5823
  this.global ? void 0 : projectPath
5692
5824
  );
5693
5825
  try {
5694
- const content = readFileSync11(fullPath, "utf-8");
5826
+ const content = readFileSync12(fullPath, "utf-8");
5695
5827
  const { parse: parseYaml2 } = await import("yaml");
5696
5828
  const data = parseYaml2(content);
5697
5829
  if (!data.learnings || !Array.isArray(data.learnings)) {
@@ -6760,14 +6892,14 @@ var TeamCommand = class extends Command29 {
6760
6892
  }
6761
6893
  const projectPath = process.cwd();
6762
6894
  const bundlePath = join12(projectPath, ".skillkit", "bundles", `${this.name}.json`);
6763
- const { existsSync: existsSync21, readFileSync: readFileSync11, writeFileSync: writeFileSync11 } = await import("fs");
6764
- if (!existsSync21(bundlePath)) {
6895
+ const { existsSync: existsSync23, readFileSync: readFileSync12, writeFileSync: writeFileSync12 } = await import("fs");
6896
+ if (!existsSync23(bundlePath)) {
6765
6897
  this.context.stderr.write(chalk21.red(`Bundle "${this.name}" not found. Create it first with bundle-create.
6766
6898
  `));
6767
6899
  return 1;
6768
6900
  }
6769
- const content = readFileSync11(bundlePath, "utf-8");
6770
- writeFileSync11(this.output, content, "utf-8");
6901
+ const content = readFileSync12(bundlePath, "utf-8");
6902
+ writeFileSync12(this.output, content, "utf-8");
6771
6903
  this.context.stdout.write(chalk21.green(`\u2713 Bundle exported to: ${this.output}
6772
6904
  `));
6773
6905
  return 0;
@@ -6777,8 +6909,8 @@ var TeamCommand = class extends Command29 {
6777
6909
  this.context.stderr.write(chalk21.red("--source <path> is required for bundle-import\n"));
6778
6910
  return 1;
6779
6911
  }
6780
- const { existsSync: existsSync21 } = await import("fs");
6781
- if (!existsSync21(this.source)) {
6912
+ const { existsSync: existsSync23 } = await import("fs");
6913
+ if (!existsSync23(this.source)) {
6782
6914
  this.context.stderr.write(chalk21.red(`Bundle file not found: ${this.source}
6783
6915
  `));
6784
6916
  return 1;
@@ -6946,8 +7078,8 @@ var PluginCommand = class extends Command30 {
6946
7078
  }
6947
7079
  const projectPath = this.global ? join13(homedir2(), ".skillkit") : process.cwd();
6948
7080
  const pluginsDir = this.global ? join13(projectPath, "plugins") : join13(projectPath, ".skillkit", "plugins");
6949
- const isLocalPath4 = this.source.startsWith("./") || this.source.startsWith("../") || this.source.startsWith("/") || this.source.startsWith("~") || this.source.includes("\\") || isAbsolute(this.source);
6950
- if (isLocalPath4 && existsSync15(resolvedSource)) {
7081
+ const isLocalPath5 = this.source.startsWith("./") || this.source.startsWith("../") || this.source.startsWith("/") || this.source.startsWith("~") || this.source.includes("\\") || isAbsolute(this.source);
7082
+ if (isLocalPath5 && existsSync15(resolvedSource)) {
6951
7083
  const targetDir = join13(pluginsDir, pluginName);
6952
7084
  const resolvedTarget = resolve13(targetDir);
6953
7085
  const resolvedPluginsDir = resolve13(pluginsDir);
@@ -10683,13 +10815,14 @@ var CheckCommand = class extends Command39 {
10683
10815
  // src/commands/find.ts
10684
10816
  init_onboarding();
10685
10817
  import { Command as Command40, Option as Option39 } from "clipanion";
10818
+ import { FederatedSearch, GitHubSkillRegistry, RateLimitError } from "@skillkit/core";
10686
10819
 
10687
10820
  // ../../marketplace/skills.json
10688
10821
  var skills_default = {
10689
10822
  $schema: "./schema.json",
10690
10823
  version: 1,
10691
- updatedAt: "2026-01-26",
10692
- totalSkills: 15064,
10824
+ updatedAt: "2026-02-02",
10825
+ totalSkills: 15065,
10693
10826
  curatedCollections: 31,
10694
10827
  skills: [
10695
10828
  {
@@ -43799,6 +43932,23 @@ var skills_default = {
43799
43932
  "k8s"
43800
43933
  ]
43801
43934
  },
43935
+ {
43936
+ id: "rohitg00/beautiful-mermaid/beautiful-mermaid",
43937
+ name: "Beautiful Mermaid",
43938
+ description: "Render Mermaid diagrams as beautiful SVGs or ASCII art. 5 diagram types, 15 themes, Shiki integration, zero DOM dependencies.",
43939
+ source: "rohitg00/beautiful-mermaid",
43940
+ tags: [
43941
+ "mermaid",
43942
+ "diagrams",
43943
+ "visualization",
43944
+ "flowchart",
43945
+ "sequence",
43946
+ "uml",
43947
+ "ascii",
43948
+ "svg",
43949
+ "themes"
43950
+ ]
43951
+ },
43802
43952
  {
43803
43953
  id: "itsmostafa/aws-agent-skills/cognito",
43804
43954
  name: "Cognito",
@@ -136344,6 +136494,9 @@ var FindCommand = class extends Command40 {
136344
136494
  quiet = Option39.Boolean("--quiet,-q", false, {
136345
136495
  description: "Minimal output (just list skills)"
136346
136496
  });
136497
+ federated = Option39.Boolean("--federated,-f", false, {
136498
+ description: "Search external registries (GitHub SKILL.md files)"
136499
+ });
136347
136500
  async execute() {
136348
136501
  const s = spinner2();
136349
136502
  const limit = parseInt(this.limit, 10) || 10;
@@ -136393,12 +136546,42 @@ var FindCommand = class extends Command40 {
136393
136546
  results = allSkills.slice(0, limit);
136394
136547
  }
136395
136548
  }
136549
+ if (this.federated && this.query) {
136550
+ s.start("Searching external registries...");
136551
+ const fedSearch = new FederatedSearch();
136552
+ fedSearch.addRegistry(new GitHubSkillRegistry());
136553
+ try {
136554
+ const fedResult = await fedSearch.search(this.query, { limit: parseInt(this.limit, 10) || 10 });
136555
+ s.stop(`Found ${fedResult.total} external skill(s) from ${fedResult.registries.join(", ") || "none"}`);
136556
+ if (fedResult.skills.length > 0) {
136557
+ console.log("");
136558
+ console.log(colors.bold("External Skills (SKILL.md):"));
136559
+ for (const skill of fedResult.skills) {
136560
+ const stars = typeof skill.stars === "number" ? colors.muted(` \u2605${skill.stars}`) : "";
136561
+ const desc = skill.description ? colors.muted(` - ${skill.description.slice(0, 50)}${skill.description.length > 50 ? "..." : ""}`) : "";
136562
+ console.log(` ${colors.cyan(symbols.bullet)} ${colors.primary(skill.name)}${stars}${desc}`);
136563
+ if (!this.quiet) {
136564
+ console.log(` ${colors.muted(skill.source)}`);
136565
+ }
136566
+ }
136567
+ console.log("");
136568
+ }
136569
+ } catch (err) {
136570
+ if (err instanceof RateLimitError) {
136571
+ s.stop(colors.warning("Rate limited by GitHub API"));
136572
+ console.log(colors.muted("Set GITHUB_TOKEN env var or wait before retrying."));
136573
+ } else {
136574
+ s.stop(colors.warning("Federated search failed"));
136575
+ }
136576
+ }
136577
+ }
136396
136578
  if (results.length === 0) {
136397
136579
  console.log(colors.muted("No skills found matching your search"));
136398
136580
  console.log("");
136399
136581
  console.log(colors.muted("Try:"));
136400
- console.log(colors.muted(" skillkit find --top # Show featured skills"));
136401
- console.log(colors.muted(" skillkit ui # Browse in TUI"));
136582
+ console.log(colors.muted(" skillkit find --top # Show featured skills"));
136583
+ console.log(colors.muted(" skillkit find -f <query> # Search external registries"));
136584
+ console.log(colors.muted(" skillkit ui # Browse in TUI"));
136402
136585
  return 0;
136403
136586
  }
136404
136587
  console.log("");
@@ -139260,6 +139443,631 @@ var TreeCommand = class extends Command49 {
139260
139443
  }
139261
139444
  };
139262
139445
 
139446
+ // src/commands/quick.ts
139447
+ init_helpers();
139448
+ init_onboarding();
139449
+ import { existsSync as existsSync21, mkdirSync as mkdirSync10, cpSync as cpSync4, rmSync as rmSync5, symlinkSync as symlinkSync2 } from "fs";
139450
+ import { join as join20, resolve as resolve21, normalize } from "path";
139451
+ import { execFile as execFile2 } from "child_process";
139452
+ import { promisify as promisify2 } from "util";
139453
+ import { Command as Command50 } from "clipanion";
139454
+ import {
139455
+ ContextManager as ContextManager3,
139456
+ RecommendationEngine as RecommendationEngine2,
139457
+ loadIndex as loadIndexFromCache4,
139458
+ isIndexStale as isIndexStale2,
139459
+ buildSkillIndex as buildSkillIndex2,
139460
+ saveIndex as saveIndex2,
139461
+ KNOWN_SKILL_REPOS as KNOWN_SKILL_REPOS2,
139462
+ isPathInside as isPathInside2,
139463
+ isLocalPath as isLocalPath4,
139464
+ detectProvider as detectProvider4
139465
+ } from "@skillkit/core";
139466
+ import { getAdapter as getAdapter6, detectAgent as detectAgent5, getAllAdapters as getAllAdapters6 } from "@skillkit/agents";
139467
+ var execFileAsync2 = promisify2(execFile2);
139468
+ function truncate6(str, maxLen) {
139469
+ if (str.length <= maxLen) return str;
139470
+ return str.slice(0, maxLen - 3) + "...";
139471
+ }
139472
+ var QuickCommand = class extends Command50 {
139473
+ static paths = [["quick"]];
139474
+ static usage = Command50.Usage({
139475
+ description: "Zero-friction skill setup: detect agents, analyze project, recommend and install",
139476
+ examples: [
139477
+ ["Quick setup", "$0 quick"]
139478
+ ]
139479
+ });
139480
+ async execute() {
139481
+ const s = spinner2();
139482
+ try {
139483
+ welcome();
139484
+ step(`${colors.bold("Quick Setup")} - zero-friction skill installation`);
139485
+ console.log("");
139486
+ s.start("Detecting installed AI agents...");
139487
+ const allAdapters = getAllAdapters6();
139488
+ const detectedAgents = [];
139489
+ for (const adapter of allAdapters) {
139490
+ try {
139491
+ const installDir = getInstallDir(false, adapter.type);
139492
+ const globalDir = getInstallDir(true, adapter.type);
139493
+ if (existsSync21(installDir) || existsSync21(globalDir) || existsSync21(adapter.configFile)) {
139494
+ detectedAgents.push(adapter.type);
139495
+ }
139496
+ } catch {
139497
+ }
139498
+ }
139499
+ if (detectedAgents.length === 0) {
139500
+ const fallback = await detectAgent5();
139501
+ detectedAgents.push(fallback);
139502
+ }
139503
+ s.stop(`Detected ${detectedAgents.length} agent${detectedAgents.length !== 1 ? "s" : ""}: ${detectedAgents.map(formatAgent).join(", ")}`);
139504
+ s.start("Analyzing project...");
139505
+ const targetPath = resolve21(process.cwd());
139506
+ const manager = new ContextManager3(targetPath);
139507
+ let context = manager.get();
139508
+ if (!context) {
139509
+ context = manager.init();
139510
+ }
139511
+ s.stop("Project analyzed");
139512
+ if (!context) {
139513
+ error("Failed to analyze project");
139514
+ return 1;
139515
+ }
139516
+ const profile = {
139517
+ name: context.project.name,
139518
+ type: context.project.type,
139519
+ stack: context.stack,
139520
+ patterns: context.patterns,
139521
+ installedSkills: context.skills?.installed || [],
139522
+ excludedSkills: context.skills?.excluded || []
139523
+ };
139524
+ const languages = profile.stack.languages.map((l) => `${l.name}${l.version ? ` ${l.version}` : ""}`);
139525
+ const frameworks = profile.stack.frameworks.map((f) => `${f.name}${f.version ? ` ${f.version}` : ""}`);
139526
+ showProjectSummary({
139527
+ name: profile.name,
139528
+ type: profile.type,
139529
+ languages,
139530
+ frameworks
139531
+ });
139532
+ let index = loadIndexFromCache4();
139533
+ if (!index || index.skills.length === 0) {
139534
+ s.start("Building skill index from known sources...");
139535
+ try {
139536
+ const result2 = await buildSkillIndex2(KNOWN_SKILL_REPOS2, (message) => {
139537
+ s.message(message);
139538
+ });
139539
+ index = result2.index;
139540
+ saveIndex2(index);
139541
+ s.stop(`Indexed ${index.skills.length} skills`);
139542
+ } catch {
139543
+ s.stop(colors.error("Failed to build index"));
139544
+ warn("Could not fetch skill index. Try running: skillkit recommend --update");
139545
+ return 1;
139546
+ }
139547
+ } else if (isIndexStale2(index)) {
139548
+ step(colors.muted('Skill index is stale. Run "skillkit recommend --update" to refresh.'));
139549
+ }
139550
+ const engine = new RecommendationEngine2();
139551
+ engine.loadIndex(index);
139552
+ const result = engine.recommend(profile, {
139553
+ limit: 5,
139554
+ minScore: 20,
139555
+ excludeInstalled: true,
139556
+ includeReasons: true
139557
+ });
139558
+ const recommendations = result.recommendations;
139559
+ if (recommendations.length === 0) {
139560
+ warn("No matching skills found for your project.");
139561
+ console.log(colors.muted("Try running: skillkit recommend --update"));
139562
+ return 0;
139563
+ }
139564
+ console.log("");
139565
+ console.log(colors.bold(`Top ${recommendations.length} Recommended Skills:`));
139566
+ console.log("");
139567
+ const options = [];
139568
+ for (let i = 0; i < recommendations.length; i++) {
139569
+ const rec = recommendations[i];
139570
+ let scoreColor;
139571
+ if (rec.score >= 70) {
139572
+ scoreColor = colors.success;
139573
+ } else if (rec.score >= 50) {
139574
+ scoreColor = colors.warning;
139575
+ } else {
139576
+ scoreColor = colors.muted;
139577
+ }
139578
+ const scoreBar = progressBar(rec.score, 100, 10);
139579
+ const qualityScore = rec.skill.quality ?? null;
139580
+ const qualityDisplay = typeof qualityScore === "number" && Number.isFinite(qualityScore) ? ` ${formatQualityBadge(qualityScore)}` : "";
139581
+ console.log(` ${colors.bold(`${i + 1}.`)} ${scoreColor(`${rec.score}%`)} ${colors.dim(scoreBar)} ${colors.bold(rec.skill.name)}${qualityDisplay}`);
139582
+ if (rec.skill.description) {
139583
+ console.log(` ${colors.muted(truncate6(rec.skill.description, 70))}`);
139584
+ }
139585
+ options.push({
139586
+ value: `${i}`,
139587
+ label: `${rec.skill.name} (${rec.score}% match)`,
139588
+ hint: rec.skill.source || void 0
139589
+ });
139590
+ }
139591
+ console.log("");
139592
+ const skipOption = { value: "skip", label: "Skip installation" };
139593
+ const selectResult = await select2({
139594
+ message: "Select a skill to install",
139595
+ options: [...options, skipOption]
139596
+ });
139597
+ if (isCancel2(selectResult) || selectResult === "skip") {
139598
+ cancel2("Quick setup complete (no installation)");
139599
+ return 0;
139600
+ }
139601
+ const selectedIndex = parseInt(selectResult, 10);
139602
+ const selectedSkill = recommendations[selectedIndex];
139603
+ if (!selectedSkill || !selectedSkill.skill.source) {
139604
+ error("Selected skill has no installable source");
139605
+ return 1;
139606
+ }
139607
+ const agentDisplay = detectedAgents.length <= 3 ? detectedAgents.map(formatAgent).join(", ") : `${detectedAgents.slice(0, 2).map(formatAgent).join(", ")} +${detectedAgents.length - 2} more`;
139608
+ const confirmResult = await confirm2({
139609
+ message: `Install ${colors.bold(selectedSkill.skill.name)} to ${agentDisplay}?`,
139610
+ initialValue: true
139611
+ });
139612
+ if (isCancel2(confirmResult) || !confirmResult) {
139613
+ cancel2("Installation cancelled");
139614
+ return 0;
139615
+ }
139616
+ saveLastAgents(detectedAgents);
139617
+ const providerAdapter = detectProvider4(selectedSkill.skill.source);
139618
+ if (!providerAdapter) {
139619
+ error(`Could not detect provider for: ${selectedSkill.skill.source}`);
139620
+ return 1;
139621
+ }
139622
+ s.start(`Fetching ${selectedSkill.skill.name}...`);
139623
+ const cloneResult = await providerAdapter.clone(selectedSkill.skill.source, "", { depth: 1 });
139624
+ if (!cloneResult.success || !cloneResult.path) {
139625
+ s.stop(colors.error(cloneResult.error || "Failed to fetch source"));
139626
+ return 1;
139627
+ }
139628
+ const discoveredSkills = cloneResult.discoveredSkills || [];
139629
+ const matchedSkill = discoveredSkills.find((ds) => ds.name === selectedSkill.skill.name) || discoveredSkills[0];
139630
+ if (!matchedSkill) {
139631
+ s.stop(colors.error("Skill not found in repository"));
139632
+ return 1;
139633
+ }
139634
+ s.stop(`Found ${selectedSkill.skill.name}`);
139635
+ let primaryPath = null;
139636
+ const installedAgents = [];
139637
+ for (const agentType of detectedAgents) {
139638
+ const adapter = getAdapter6(agentType);
139639
+ const installDir = getInstallDir(false, agentType);
139640
+ if (!existsSync21(installDir)) {
139641
+ mkdirSync10(installDir, { recursive: true });
139642
+ }
139643
+ const sanitizedName = matchedSkill.name.split(/[/\\]/).pop() || matchedSkill.name;
139644
+ const targetInstallPath = normalize(join20(installDir, sanitizedName));
139645
+ if (!isPathInside2(targetInstallPath, installDir)) {
139646
+ error(`Skipping ${matchedSkill.name} for ${adapter.name} (install path escapes target directory)`);
139647
+ continue;
139648
+ }
139649
+ const securityRoot = cloneResult.tempRoot || cloneResult.path;
139650
+ if (!isPathInside2(matchedSkill.path, securityRoot)) {
139651
+ error(`Skipping ${matchedSkill.name} for ${adapter.name} (path traversal detected)`);
139652
+ continue;
139653
+ }
139654
+ const useSymlink = detectedAgents.length > 1 && primaryPath !== null;
139655
+ s.start(`Installing to ${adapter.name}${useSymlink ? " (symlink)" : ""}...`);
139656
+ try {
139657
+ if (existsSync21(targetInstallPath)) {
139658
+ rmSync5(targetInstallPath, { recursive: true, force: true });
139659
+ }
139660
+ if (useSymlink && primaryPath) {
139661
+ symlinkSync2(primaryPath, targetInstallPath, "dir");
139662
+ } else {
139663
+ cpSync4(matchedSkill.path, targetInstallPath, { recursive: true, dereference: true });
139664
+ if (detectedAgents.length > 1 && primaryPath === null) {
139665
+ primaryPath = targetInstallPath;
139666
+ }
139667
+ const packageJsonPath = join20(targetInstallPath, "package.json");
139668
+ if (existsSync21(packageJsonPath)) {
139669
+ s.stop(`Installed to ${adapter.name}`);
139670
+ s.start("Installing npm dependencies...");
139671
+ try {
139672
+ await execFileAsync2("npm", ["install", "--production"], { cwd: targetInstallPath });
139673
+ s.stop("Dependencies installed");
139674
+ } catch {
139675
+ s.stop(colors.warning("Dependencies failed"));
139676
+ console.log(colors.muted("Run manually: npm install in " + targetInstallPath));
139677
+ }
139678
+ s.start("Finishing installation...");
139679
+ }
139680
+ }
139681
+ const metadata = {
139682
+ name: matchedSkill.name,
139683
+ description: selectedSkill.skill.description || "",
139684
+ source: selectedSkill.skill.source,
139685
+ sourceType: providerAdapter.type,
139686
+ subpath: matchedSkill.name,
139687
+ installedAt: (/* @__PURE__ */ new Date()).toISOString(),
139688
+ enabled: true
139689
+ };
139690
+ saveSkillMetadata(targetInstallPath, metadata);
139691
+ installedAgents.push(agentType);
139692
+ s.stop(`Installed to ${adapter.name}${useSymlink ? " (symlink)" : ""}`);
139693
+ } catch (err) {
139694
+ s.stop(colors.error(`Failed to install to ${adapter.name}`));
139695
+ console.log(colors.muted(err instanceof Error ? err.message : String(err)));
139696
+ }
139697
+ }
139698
+ const cleanupPath = cloneResult.tempRoot || cloneResult.path;
139699
+ if (!isLocalPath4(selectedSkill.skill.source) && cleanupPath && existsSync21(cleanupPath)) {
139700
+ rmSync5(cleanupPath, { recursive: true, force: true });
139701
+ }
139702
+ if (installedAgents.length > 0) {
139703
+ console.log("");
139704
+ success(`Installed ${colors.bold(matchedSkill.name)} to ${installedAgents.length} agent${installedAgents.length !== 1 ? "s" : ""}`);
139705
+ for (const a of installedAgents) {
139706
+ console.log(colors.muted(` ${symbols.success} ${getAgentIcon(a)} ${formatAgent(a)}`));
139707
+ }
139708
+ console.log("");
139709
+ const badgeUrl = `https://img.shields.io/badge/SkillKit-${encodeURIComponent(matchedSkill.name)}-black?style=flat-square`;
139710
+ console.log(colors.dim("Add to your README:"));
139711
+ console.log(colors.muted(` [![SkillKit](${badgeUrl})](https://agenstskills.com)`));
139712
+ outro2("Quick setup complete!");
139713
+ console.log("");
139714
+ console.log(colors.muted("Next steps:"));
139715
+ console.log(colors.muted(` ${symbols.arrowRight} Run ${colors.cyan("skillkit sync")} to update agent configs`));
139716
+ console.log(colors.muted(` ${symbols.arrowRight} Run ${colors.cyan("skillkit recommend")} for more suggestions`));
139717
+ console.log(colors.muted(` ${symbols.arrowRight} Run ${colors.cyan("skillkit list")} to see installed skills`));
139718
+ console.log("");
139719
+ } else {
139720
+ warn("No agents were installed");
139721
+ }
139722
+ return 0;
139723
+ } catch (err) {
139724
+ s.stop(colors.error("Quick setup failed"));
139725
+ console.log(colors.muted(err instanceof Error ? err.message : String(err)));
139726
+ return 1;
139727
+ }
139728
+ }
139729
+ };
139730
+
139731
+ // src/commands/skillmd.ts
139732
+ init_onboarding();
139733
+ import { existsSync as existsSync22, readFileSync as readFileSync11, writeFileSync as writeFileSync11, readdirSync as readdirSync4 } from "fs";
139734
+ import { join as join21, resolve as resolve22, basename as basename6, relative } from "path";
139735
+ import { Command as Command51, Option as Option49 } from "clipanion";
139736
+ function validateSkillMd(filePath) {
139737
+ const result = {
139738
+ path: filePath,
139739
+ exists: false,
139740
+ hasName: false,
139741
+ hasDescription: false,
139742
+ hasTriggers: false,
139743
+ hasCapabilities: false,
139744
+ triggerCount: 0,
139745
+ capabilityCount: 0,
139746
+ score: 0,
139747
+ issues: []
139748
+ };
139749
+ if (!existsSync22(filePath)) {
139750
+ result.issues.push("File does not exist");
139751
+ return result;
139752
+ }
139753
+ result.exists = true;
139754
+ const content = readFileSync11(filePath, "utf-8");
139755
+ if (!content.trim()) {
139756
+ result.issues.push("File is empty");
139757
+ return result;
139758
+ }
139759
+ const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
139760
+ const bodyContent = frontmatterMatch ? content.slice(frontmatterMatch[0].length) : content;
139761
+ if (frontmatterMatch) {
139762
+ const frontmatter = frontmatterMatch[1];
139763
+ if (/^name:\s*.+$/m.test(frontmatter)) result.hasName = true;
139764
+ if (/^description:\s*.+$/m.test(frontmatter)) result.hasDescription = true;
139765
+ }
139766
+ if (!result.hasName) {
139767
+ if (/^#\s+.+$/m.test(bodyContent)) result.hasName = true;
139768
+ }
139769
+ if (!result.hasDescription) {
139770
+ if (/^##?\s*(description|about|overview)\b/im.test(bodyContent)) {
139771
+ result.hasDescription = true;
139772
+ } else {
139773
+ const lines = bodyContent.split(/\r?\n/).filter((l) => l.trim());
139774
+ const nonHeaderLines = lines.filter((l) => !l.startsWith("#"));
139775
+ if (nonHeaderLines.length >= 2) result.hasDescription = true;
139776
+ }
139777
+ }
139778
+ const triggerPatterns = [
139779
+ /triggers?\s*when/i,
139780
+ /when\s*to\s*use/i,
139781
+ /use\s*this\s*when/i,
139782
+ /\*\*triggers?\b/i,
139783
+ /^[-*]\s+.+(when|if|pattern|trigger)/im,
139784
+ /glob:/i
139785
+ ];
139786
+ for (const pattern of triggerPatterns) {
139787
+ if (pattern.test(content)) {
139788
+ result.hasTriggers = true;
139789
+ break;
139790
+ }
139791
+ }
139792
+ if (result.hasTriggers) {
139793
+ const triggerSection = content.match(/triggers?\s*when[:\s]*\n((?:[-*]\s+.+\n?)+)/i);
139794
+ result.triggerCount = triggerSection ? (triggerSection[1].match(/^[-*]\s+/gm) || []).length : 1;
139795
+ }
139796
+ const capabilityPatterns = [
139797
+ /capabilities?[:\s]/i,
139798
+ /features?[:\s]/i,
139799
+ /what\s*(it|this)\s*(does|can)/i,
139800
+ /^##?\s*capabilities/im,
139801
+ /^##?\s*features/im
139802
+ ];
139803
+ for (const pattern of capabilityPatterns) {
139804
+ if (pattern.test(content)) {
139805
+ result.hasCapabilities = true;
139806
+ break;
139807
+ }
139808
+ }
139809
+ if (result.hasCapabilities) {
139810
+ const capSection = content.match(/(?:capabilities?|features?)[:\s]*\n((?:[-*]\s+.+\n?)+)/i);
139811
+ result.capabilityCount = capSection ? (capSection[1].match(/^[-*]\s+/gm) || []).length : 1;
139812
+ }
139813
+ if (!result.hasName) result.issues.push("Missing name field");
139814
+ if (!result.hasDescription) result.issues.push("Missing description section");
139815
+ if (!result.hasTriggers) result.issues.push("No trigger patterns found");
139816
+ if (!result.hasCapabilities) result.issues.push("No capabilities list found");
139817
+ let score = 0;
139818
+ if (result.exists) score += 10;
139819
+ if (result.hasName) score += 20;
139820
+ if (result.hasDescription) score += 25;
139821
+ if (result.hasTriggers) score += 20;
139822
+ if (result.hasCapabilities) score += 15;
139823
+ if (result.triggerCount >= 3) score += 5;
139824
+ if (result.capabilityCount >= 3) score += 5;
139825
+ if (frontmatterMatch) {
139826
+ const fm = frontmatterMatch[1];
139827
+ if (/^version:/m.test(fm)) score += 3;
139828
+ if (/^license:/m.test(fm)) score += 2;
139829
+ if (/^tags:/m.test(fm)) score += 3;
139830
+ if (/^metadata:/m.test(fm)) score += 2;
139831
+ }
139832
+ result.score = Math.min(100, score);
139833
+ return result;
139834
+ }
139835
+ function printValidation(validation, verbose = false) {
139836
+ const scoreColor = validation.score >= 80 ? colors.success : validation.score >= 60 ? colors.warning : colors.error;
139837
+ console.log(` ${colors.muted("Score:")} ${scoreColor(`${validation.score}`)}/100`);
139838
+ console.log(` ${validation.hasName ? colors.success(symbols.success) : colors.error(symbols.error)} Name field`);
139839
+ console.log(` ${validation.hasDescription ? colors.success(symbols.success) : colors.error(symbols.error)} Description section`);
139840
+ console.log(` ${validation.hasTriggers ? colors.success(symbols.success) : colors.error(symbols.error)} Trigger patterns${validation.triggerCount > 0 ? ` (${validation.triggerCount})` : ""}`);
139841
+ console.log(` ${validation.hasCapabilities ? colors.success(symbols.success) : colors.error(symbols.error)} Capabilities list${validation.capabilityCount > 0 ? ` (${validation.capabilityCount})` : ""}`);
139842
+ if (verbose && validation.issues.length > 0) {
139843
+ console.log("");
139844
+ console.log(` ${colors.warning("Issues:")}`);
139845
+ for (const issue of validation.issues) {
139846
+ console.log(` ${colors.warning(symbols.warning)} ${issue}`);
139847
+ }
139848
+ }
139849
+ }
139850
+ var SkillMdValidateCommand = class extends Command51 {
139851
+ static paths = [["skillmd", "validate"], ["skill-md", "validate"]];
139852
+ static usage = Command51.Usage({
139853
+ description: "Validate a SKILL.md file against the standard",
139854
+ examples: [
139855
+ ["Validate SKILL.md in current directory", "$0 skillmd validate"],
139856
+ ["Validate specific file", "$0 skillmd validate ./path/to/SKILL.md"]
139857
+ ]
139858
+ });
139859
+ targetPath = Option49.String({ required: false, name: "path" });
139860
+ verbose = Option49.Boolean("--verbose,-v", false, {
139861
+ description: "Show detailed validation results"
139862
+ });
139863
+ json = Option49.Boolean("--json", false, {
139864
+ description: "Output as JSON"
139865
+ });
139866
+ async execute() {
139867
+ const targetPath = this.targetPath || join21(process.cwd(), "SKILL.md");
139868
+ const resolvedPath = resolve22(targetPath);
139869
+ const filePath = resolvedPath.endsWith("SKILL.md") ? resolvedPath : join21(resolvedPath, "SKILL.md");
139870
+ if (!this.json) {
139871
+ header("SKILL.md Validation");
139872
+ step(`Validating: ${colors.cyan(filePath)}`);
139873
+ console.log("");
139874
+ }
139875
+ const validation = validateSkillMd(filePath);
139876
+ if (this.json) {
139877
+ console.log(JSON.stringify(validation, null, 2));
139878
+ return validation.score >= 60 ? 0 : 1;
139879
+ }
139880
+ console.log(colors.primary(basename6(filePath)));
139881
+ printValidation(validation, this.verbose);
139882
+ console.log("");
139883
+ if (validation.score >= 80) {
139884
+ success(`SKILL.md is compliant (score: ${validation.score}/100)`);
139885
+ } else if (validation.score >= 60) {
139886
+ warn(`SKILL.md needs improvement (score: ${validation.score}/100)`);
139887
+ } else {
139888
+ error(`SKILL.md does not meet minimum standard (score: ${validation.score}/100)`);
139889
+ }
139890
+ return validation.score >= 60 ? 0 : 1;
139891
+ }
139892
+ };
139893
+ var SkillMdInitCommand = class extends Command51 {
139894
+ static paths = [["skillmd", "init"], ["skill-md", "init"]];
139895
+ static usage = Command51.Usage({
139896
+ description: "Create a template SKILL.md in the current directory",
139897
+ examples: [
139898
+ ["Create SKILL.md template", "$0 skillmd init"],
139899
+ ["Create with custom name", "$0 skillmd init --name my-skill"]
139900
+ ]
139901
+ });
139902
+ name = Option49.String("--name,-n", {
139903
+ description: "Skill name"
139904
+ });
139905
+ force = Option49.Boolean("--force,-f", false, {
139906
+ description: "Overwrite existing SKILL.md"
139907
+ });
139908
+ async execute() {
139909
+ const outputPath = join21(process.cwd(), "SKILL.md");
139910
+ if (existsSync22(outputPath) && !this.force) {
139911
+ warn("SKILL.md already exists");
139912
+ console.log(colors.muted("Use --force to overwrite"));
139913
+ return 1;
139914
+ }
139915
+ const skillName = this.name || basename6(process.cwd());
139916
+ const formattedName = skillName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
139917
+ const template = [
139918
+ "---",
139919
+ `name: ${skillName}`,
139920
+ "description: What this skill does and when to use it",
139921
+ 'version: "1.0"',
139922
+ "license: MIT",
139923
+ "tags: [general]",
139924
+ "metadata:",
139925
+ " author: your-name",
139926
+ "---",
139927
+ "",
139928
+ `# ${formattedName}`,
139929
+ "",
139930
+ "Brief description of what this skill provides to AI coding agents.",
139931
+ "",
139932
+ "## Triggers when:",
139933
+ `- User asks about ${skillName} related tasks`,
139934
+ `- Project contains ${skillName} configuration files`,
139935
+ `- Code changes involve ${skillName} patterns`,
139936
+ "",
139937
+ "## Capabilities:",
139938
+ `- Provides best practices for ${skillName}`,
139939
+ "- Generates boilerplate code and configurations",
139940
+ "- Validates existing implementations",
139941
+ "- Suggests improvements and optimizations",
139942
+ "",
139943
+ "## Steps",
139944
+ "1. First step the AI agent should take",
139945
+ "2. Second step with specific instructions",
139946
+ "3. Third step with expected outcome",
139947
+ "",
139948
+ "## Examples",
139949
+ "",
139950
+ "```",
139951
+ "Example code or configuration here",
139952
+ "```",
139953
+ ""
139954
+ ].join("\n");
139955
+ writeFileSync11(outputPath, template);
139956
+ success(`Created SKILL.md for "${skillName}"`);
139957
+ console.log("");
139958
+ console.log(colors.muted("Next steps:"));
139959
+ console.log(` ${colors.cyan("1.")} Edit SKILL.md with your skill instructions`);
139960
+ console.log(` ${colors.cyan("2.")} Run ${colors.cyan("skillkit skillmd validate")} to check compliance`);
139961
+ console.log(` ${colors.cyan("3.")} Run ${colors.cyan("skillkit publish submit")} to share with the marketplace`);
139962
+ return 0;
139963
+ }
139964
+ };
139965
+ var SkillMdCheckCommand = class extends Command51 {
139966
+ static paths = [["skillmd", "check"], ["skill-md", "check"]];
139967
+ static usage = Command51.Usage({
139968
+ description: "Check all SKILL.md files in the project for compliance",
139969
+ examples: [
139970
+ ["Check current directory", "$0 skillmd check"],
139971
+ ["Check specific directory", "$0 skillmd check ./skills"]
139972
+ ]
139973
+ });
139974
+ targetPath = Option49.String({ required: false, name: "path" });
139975
+ verbose = Option49.Boolean("--verbose,-v", false, {
139976
+ description: "Show detailed validation results"
139977
+ });
139978
+ async execute() {
139979
+ const targetPath = resolve22(this.targetPath || process.cwd());
139980
+ header("SKILL.md Compliance Check");
139981
+ const s = spinner2();
139982
+ s.start("Scanning for SKILL.md files...");
139983
+ const skillMdFiles = this.findSkillMdFiles(targetPath);
139984
+ s.stop(`Found ${skillMdFiles.length} SKILL.md file(s)`);
139985
+ if (skillMdFiles.length === 0) {
139986
+ warn("No SKILL.md files found");
139987
+ console.log(colors.muted(`Searched: ${targetPath}`));
139988
+ console.log("");
139989
+ console.log(colors.muted("Create one with:"));
139990
+ console.log(` ${colors.cyan("skillkit skillmd init")}`);
139991
+ return 0;
139992
+ }
139993
+ const validations = skillMdFiles.map((f) => validateSkillMd(f));
139994
+ validations.sort((a, b) => b.score - a.score);
139995
+ console.log("");
139996
+ for (const validation of validations) {
139997
+ const relativePath = relative(targetPath, validation.path);
139998
+ const scoreColor = validation.score >= 80 ? colors.success : validation.score >= 60 ? colors.warning : colors.error;
139999
+ console.log(`${scoreColor(symbols.bullet)} ${colors.primary(relativePath)} ${colors.muted(`(${validation.score}/100)`)}`);
140000
+ if (this.verbose) {
140001
+ printValidation(validation, true);
140002
+ console.log("");
140003
+ }
140004
+ }
140005
+ console.log("");
140006
+ const passing = validations.filter((v) => v.score >= 60).length;
140007
+ const failing = validations.filter((v) => v.score < 60).length;
140008
+ const avgScore = Math.round(validations.reduce((sum, v) => sum + v.score, 0) / validations.length);
140009
+ console.log(colors.muted("Summary:"));
140010
+ console.log(` ${colors.muted("Total:")} ${validations.length}`);
140011
+ console.log(` ${colors.success(symbols.success)} Passing (60+): ${passing}`);
140012
+ if (failing > 0) {
140013
+ console.log(` ${colors.error(symbols.error)} Failing: ${failing}`);
140014
+ }
140015
+ console.log(` ${colors.muted("Average score:")} ${avgScore}/100`);
140016
+ console.log("");
140017
+ if (failing > 0) {
140018
+ error(`${failing} SKILL.md file(s) below minimum standard`);
140019
+ return 1;
140020
+ }
140021
+ success("All SKILL.md files are compliant");
140022
+ return 0;
140023
+ }
140024
+ findSkillMdFiles(dir) {
140025
+ const results = [];
140026
+ const directFile = join21(dir, "SKILL.md");
140027
+ if (existsSync22(directFile)) results.push(directFile);
140028
+ const searchDirs = [
140029
+ join21(dir, "skills"),
140030
+ join21(dir, ".claude", "skills"),
140031
+ join21(dir, ".cursor", "skills"),
140032
+ join21(dir, ".codex", "skills"),
140033
+ join21(dir, ".github", "skills")
140034
+ ];
140035
+ for (const searchDir of searchDirs) {
140036
+ if (!existsSync22(searchDir)) continue;
140037
+ this.scanDir(searchDir, results, 0);
140038
+ }
140039
+ try {
140040
+ const entries = readdirSync4(dir, { withFileTypes: true });
140041
+ for (const entry of entries) {
140042
+ if (!entry.isDirectory()) continue;
140043
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
140044
+ const entrySkillMd = join21(dir, entry.name, "SKILL.md");
140045
+ if (existsSync22(entrySkillMd) && !results.includes(entrySkillMd)) {
140046
+ results.push(entrySkillMd);
140047
+ }
140048
+ }
140049
+ } catch {
140050
+ }
140051
+ return results;
140052
+ }
140053
+ scanDir(dir, results, depth) {
140054
+ if (depth > 3) return;
140055
+ try {
140056
+ const entries = readdirSync4(dir, { withFileTypes: true });
140057
+ for (const entry of entries) {
140058
+ const entryPath = join21(dir, entry.name);
140059
+ if (entry.isFile() && entry.name === "SKILL.md") {
140060
+ if (!results.includes(entryPath)) results.push(entryPath);
140061
+ }
140062
+ if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
140063
+ this.scanDir(entryPath, results, depth + 1);
140064
+ }
140065
+ }
140066
+ } catch {
140067
+ }
140068
+ }
140069
+ };
140070
+
139263
140071
  // src/index.ts
139264
140072
  init_helpers();
139265
140073
  export {
@@ -139329,6 +140137,7 @@ export {
139329
140137
  ProfileRemoveCommand,
139330
140138
  PublishCommand,
139331
140139
  PublishSubmitCommand,
140140
+ QuickCommand,
139332
140141
  ReadCommand,
139333
140142
  RecommendCommand,
139334
140143
  RemoveCommand,
@@ -139343,6 +140152,9 @@ export {
139343
140152
  SessionStartCommand,
139344
140153
  SessionStatusCommand,
139345
140154
  SettingsCommand,
140155
+ SkillMdCheckCommand,
140156
+ SkillMdInitCommand,
140157
+ SkillMdValidateCommand,
139346
140158
  StatusCommand,
139347
140159
  SyncCommand,
139348
140160
  TeamCommand,