skillscat 0.1.1 → 0.1.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAsBA,UAAU,UAAU;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAiBD,wBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwS5E"}
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAsBA,UAAU,UAAU;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAwBD,wBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2T5E"}
package/dist/index.js CHANGED
@@ -1992,6 +1992,12 @@ const AGENTS = [
1992
1992
  projectPath: '.opencode/skill/',
1993
1993
  globalPath: join(homedir(), '.config', 'opencode', 'skill')
1994
1994
  },
1995
+ {
1996
+ id: 'openclaw',
1997
+ name: 'OpenClaw',
1998
+ projectPath: 'skills/',
1999
+ globalPath: join(homedir(), '.openclaw', 'skills')
2000
+ },
1995
2001
  {
1996
2002
  id: 'qoder',
1997
2003
  name: 'Qoder',
@@ -2316,14 +2322,17 @@ async function add(source, options) {
2316
2322
  }
2317
2323
  const discoverSpinner = spinner('Discovering skills');
2318
2324
  let resolvedSkills = [];
2325
+ let selectionMode = 'default';
2319
2326
  try {
2320
- resolvedSkills = await resolveInstallSkills({
2327
+ const resolution = await resolveInstallSkills({
2321
2328
  sourceInput: source,
2322
2329
  repoSource,
2323
2330
  requestedSkillNames: options.skill ?? [],
2324
2331
  explicitRefBypassRegistry: isExplicitGitHubRefSource,
2325
2332
  githubSnapshot,
2326
2333
  });
2334
+ resolvedSkills = resolution.resolved;
2335
+ selectionMode = resolution.selectionMode;
2327
2336
  }
2328
2337
  catch (err) {
2329
2338
  discoverSpinner.stop(false);
@@ -2363,6 +2372,20 @@ async function add(source, options) {
2363
2372
  console.log(` ${pc.cyan(`npx skillscat add ${source}`)}`);
2364
2373
  return;
2365
2374
  }
2375
+ if (selectionMode === 'install-all' && !options.yes && (!options.skill || options.skill.length === 0)) {
2376
+ console.log();
2377
+ info$1(`No published skill slug matched ${pc.cyan(sourceLabel)}.`);
2378
+ console.log(pc.dim(`Found ${resolvedSkills.length} published skill(s) in repository ${sourceLabel}:`));
2379
+ for (const entry of resolvedSkills) {
2380
+ console.log(pc.dim(` - ${entry.skill.name}${formatSkillPathHint(entry.skill.path)}`));
2381
+ }
2382
+ console.log();
2383
+ const confirm = await prompt(`Install all ${resolvedSkills.length} skill(s) from ${sourceLabel}? [y/N] `);
2384
+ if (confirm.trim().toLowerCase() !== 'y') {
2385
+ info$1('Installation cancelled.');
2386
+ process.exit(0);
2387
+ }
2388
+ }
2366
2389
  // Final name filter (safety net after mixed registry+git resolution)
2367
2390
  let selectedEntries = resolvedSkills;
2368
2391
  if (options.skill && options.skill.length > 0) {
@@ -2376,7 +2399,7 @@ async function add(source, options) {
2376
2399
  process.exit(1);
2377
2400
  }
2378
2401
  }
2379
- else if (!options.yes && resolvedSkills.length > 1) {
2402
+ else if (selectionMode !== 'install-all' && !options.yes && resolvedSkills.length > 1) {
2380
2403
  selectedEntries = [await selectSingleSkillInteractive(resolvedSkills)];
2381
2404
  }
2382
2405
  // Detect or select agents
@@ -2548,9 +2571,24 @@ async function add(source, options) {
2548
2571
  async function resolveInstallSkills({ sourceInput, repoSource, requestedSkillNames, explicitRefBypassRegistry, githubSnapshot, }) {
2549
2572
  const requestedNamesLower = new Set(requestedSkillNames.map((name) => name.toLowerCase()));
2550
2573
  const needsRegistryFirst = repoSource.platform === 'github' && !explicitRefBypassRegistry;
2574
+ const preferSlugLookup = isAmbiguousSlugOrRepoInput(sourceInput, repoSource);
2575
+ const canShortCircuitExactSlug = preferSlugLookup && requestedNamesLower.size === 0;
2551
2576
  let resolved = [];
2577
+ let selectionMode = 'default';
2552
2578
  let registryRepoMatchesFound = false;
2553
2579
  let registrySummariesNeedingGitBackfill = [];
2580
+ if (canShortCircuitExactSlug) {
2581
+ const registrySlugSkill = await fetchSkill(sourceInput).catch((err) => {
2582
+ verboseLog(`Registry slug lookup failed: ${err instanceof Error ? err.message : 'unknown'}`);
2583
+ return null;
2584
+ });
2585
+ if (registrySlugSkill?.content) {
2586
+ return {
2587
+ resolved: [toRegistryResolvedSkill(registrySlugSkill, sourceInput, repoSource)],
2588
+ selectionMode,
2589
+ };
2590
+ }
2591
+ }
2554
2592
  if (needsRegistryFirst) {
2555
2593
  try {
2556
2594
  const registryRepo = await fetchSkillsByRepo(repoSource.owner, repoSource.repo, {
@@ -2567,6 +2605,9 @@ async function resolveInstallSkills({ sourceInput, repoSource, requestedSkillNam
2567
2605
  if (requestedNamesLower.size > 0) {
2568
2606
  selectedSummaries = summaries.filter((item) => requestedNamesLower.has(item.name.toLowerCase()));
2569
2607
  }
2608
+ else if (preferSlugLookup) {
2609
+ selectionMode = 'install-all';
2610
+ }
2570
2611
  if (selectedSummaries.length > 0) {
2571
2612
  const registryFetch = await fetchRegistryResolvedSkills(selectedSummaries, sourceInput, repoSource);
2572
2613
  resolved.push(...registryFetch.resolved);
@@ -2612,7 +2653,10 @@ async function resolveInstallSkills({ sourceInput, repoSource, requestedSkillNam
2612
2653
  const registrySkill = await fetchSkill(sourceInput).catch(() => null);
2613
2654
  if (registrySkill?.content) {
2614
2655
  resolved.push(toRegistryResolvedSkill(registrySkill, sourceInput, repoSource));
2615
- return mergeResolvedSkills([], resolved);
2656
+ return {
2657
+ resolved: mergeResolvedSkills([], resolved),
2658
+ selectionMode,
2659
+ };
2616
2660
  }
2617
2661
  }
2618
2662
  // If some registry skills were already resolved (partial hit), keep them.
@@ -2620,7 +2664,10 @@ async function resolveInstallSkills({ sourceInput, repoSource, requestedSkillNam
2620
2664
  if (getMissingRequestedNames(requestedSkillNames, resolved).length > 0) {
2621
2665
  throw err;
2622
2666
  }
2623
- return mergeResolvedSkills([], resolved);
2667
+ return {
2668
+ resolved: mergeResolvedSkills([], resolved),
2669
+ selectionMode,
2670
+ };
2624
2671
  }
2625
2672
  throw err;
2626
2673
  }
@@ -2628,7 +2675,10 @@ async function resolveInstallSkills({ sourceInput, repoSource, requestedSkillNam
2628
2675
  if (requestedNamesLower.size > 0 && resolved.length > 0) {
2629
2676
  resolved = resolved.filter((entry) => requestedNamesLower.has(entry.skill.name.toLowerCase()));
2630
2677
  }
2631
- return mergeResolvedSkills([], resolved);
2678
+ return {
2679
+ resolved: mergeResolvedSkills([], resolved),
2680
+ selectionMode,
2681
+ };
2632
2682
  }
2633
2683
  async function fetchRegistryResolvedSkills(summaries, sourceInput, repoSource) {
2634
2684
  const resolved = [];
@@ -2917,10 +2967,21 @@ function normalizeSkillPath(path) {
2917
2967
  return '';
2918
2968
  return normalized.replace(/(?:^|\/)SKILL\.md$/i, '');
2919
2969
  }
2970
+ function formatSkillPathHint(path) {
2971
+ const normalized = normalizeSkillPath(path);
2972
+ return normalized ? ` (${normalized})` : '';
2973
+ }
2920
2974
  function toSkillFilePath(path) {
2921
2975
  const normalized = normalizeSkillPath(path);
2922
2976
  return normalized ? `${normalized}/SKILL.md` : 'SKILL.md';
2923
2977
  }
2978
+ function isAmbiguousSlugOrRepoInput(sourceInput, repoSource) {
2979
+ return (repoSource.platform === 'github'
2980
+ && !repoSource.path
2981
+ && !repoSource.branch
2982
+ && repoSource.hasExplicitRef !== true
2983
+ && sourceInput.trim() === `${repoSource.owner}/${repoSource.repo}`);
2984
+ }
2924
2985
  function getSourceFromRegistrySkill(skill) {
2925
2986
  if (skill.githubUrl) {
2926
2987
  const source = parseSource(skill.githubUrl);
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/utils/agents/agents.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmBD,eAAO,MAAM,MAAM,EAAE,KAAK,EAmHzB,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,KAAK,EAAE,CAM/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAErD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAGrF"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/utils/agents/agents.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmBD,eAAO,MAAM,MAAM,EAAE,KAAK,EAyHzB,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,KAAK,EAAE,CAM/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,CAErD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAGrF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillscat",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "CLI for installing AI agent skills from SkillsCat registry",
5
5
  "type": "module",
6
6
  "bin": {