skillmds 1.3.3 → 1.3.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to `skillmds` are documented here. Versions follow [semver](https://semver.org).
4
4
 
5
+ ## 1.3.4
6
+
7
+ - **A companion file that its source repo no longer serves no longer fails the install.** When a registry pack links to a file the upstream repo has since deleted or moved, `add` (and the MCP install tool) now installs everything else and warns which files are missing, e.g. `1 companion file is gone from the source repo and was not installed (scripts/gone.ts)`. Before, one such link failed the whole bundle and `add owner/name` fell back to fetching the slug as a GitHub repo, ending in a misleading 404 with nothing installed. `update` stays strict: it never replaces a full install with a partial one.
8
+
5
9
  ## 1.2.0
6
10
 
7
11
  `skillmd add` was rewritten. It no longer copies a skill into every agent folder it can find: it writes **one canonical copy** and links that copy into the agents you chose, in the scope you chose, and records what it did in a lock file.
package/README.md CHANGED
@@ -186,7 +186,7 @@ No auth required. It exposes `skillmd_search`, `skillmd_get`, `skillmd_download`
186
186
 
187
187
  ## Find skills on skillmd.com
188
188
 
189
- The registry behind these tools is [skillmd.com](https://skillmd.com): 25,000+ Agent Skills, each linted, security-scanned and content-pinned.
189
+ The registry behind these tools is [skillmd.com](https://skillmd.com): 1,000,000+ Agent Skills, each linted, security-scanned and content-pinned.
190
190
 
191
191
  - [Search all skills](https://skillmd.com/search) · [browse by category](https://skillmd.com/categories) · [by publisher](https://skillmd.com/publishers)
192
192
  - Install guides per agent: [Claude Code](https://skillmd.com/agents/claude-code) · [Cursor](https://skillmd.com/agents/cursor) · [Codex](https://skillmd.com/agents/codex) · [all 60+ agents](https://skillmd.com/agents)
@@ -197,7 +197,13 @@ async function fetchBundle(base, slug, token, opts = {}) {
197
197
  contents = Buffer.from(f.content_base64, "base64");
198
198
  } else if (f.source_url && isAllowedSourceUrl(f.source_url)) {
199
199
  const r = await doFetch(f.source_url).catch(() => null);
200
- if (!r || !r.ok) throw new Error(`could not fetch companion file "${f.path}" from ${hostOf(f.source_url)}`);
200
+ if (!r || !r.ok) {
201
+ if (opts.missing) {
202
+ opts.missing.push(f.path);
203
+ continue;
204
+ }
205
+ throw new Error(`could not fetch companion file "${f.path}" from ${hostOf(f.source_url)}`);
206
+ }
201
207
  contents = Buffer.from(await r.arrayBuffer());
202
208
  fromUrl = true;
203
209
  } else {
@@ -215,6 +221,12 @@ async function fetchBundle(base, slug, token, opts = {}) {
215
221
  }
216
222
  return out;
217
223
  }
224
+ function missingFilesNote(paths) {
225
+ const n = paths.length;
226
+ const shown = paths.slice(0, 5).join(", ") + (n > 5 ? `, and ${n - 5} more` : "");
227
+ const [f, was, it] = n === 1 ? ["file is", "was", "it"] : ["files are", "were", "them"];
228
+ return `${n} companion ${f} gone from the source repo and ${was} not installed (${shown}); the skill may still refer to ${it}`;
229
+ }
218
230
 
219
231
  // src/source.ts
220
232
  import { existsSync as existsSync2, statSync, lstatSync, readFileSync as readFileSync2, readdirSync, mkdtempSync, rmSync } from "fs";
@@ -841,6 +853,7 @@ export {
841
853
  RegistryError,
842
854
  createClient,
843
855
  fetchBundle,
856
+ missingFilesNote,
844
857
  skillMdFor,
845
858
  resolveSource,
846
859
  collectFiles,
package/dist/cli.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  isSkillDirOrLink,
17
17
  listInstalled,
18
18
  looksLikeProject,
19
+ missingFilesNote,
19
20
  parseSource,
20
21
  readConfig,
21
22
  readLock,
@@ -30,7 +31,7 @@ import {
30
31
  uninstallSkill,
31
32
  upsertEntry,
32
33
  writeConfig
33
- } from "./chunk-FVWCI37S.js";
34
+ } from "./chunk-6JVWN3IG.js";
34
35
 
35
36
  // src/index.ts
36
37
  import { Command as Command13 } from "commander";
@@ -870,6 +871,11 @@ function unverifiedFilesNote(n) {
870
871
  const [f, it] = n === 1 ? ["file", "it"] : ["files", "them"];
871
872
  return `${n} companion ${f} came straight from the source repo \u2014 the registry holds no checksum for ${it}, so only the connection was verified`;
872
873
  }
874
+ function bundleNote(bundle, missing) {
875
+ const unverified = bundle.filter((file) => file.unverified).length;
876
+ const notes = [unverified ? unverifiedFilesNote(unverified) : "", missing.length ? missingFilesNote(missing) : ""].filter(Boolean);
877
+ return notes.length ? notes.join("; ") : void 0;
878
+ }
873
879
  function registryFallbackNote(host) {
874
880
  return `installed from GitHub because the SkillMD registry (${host}) was unreachable \u2014 this copy is not the registry-reviewed version`;
875
881
  }
@@ -912,15 +918,16 @@ async function registryCandidate(owner, name, source, client) {
912
918
  securityFlags: skill.security_flags
913
919
  };
914
920
  if (skill.type === "pack") {
915
- const bundle = await fetchBundle(client.base, registrySlug, client.token);
921
+ const missing = [];
922
+ const bundle = await fetchBundle(client.base, registrySlug, client.token, { missing });
916
923
  if (bundle && bundle.length) {
917
924
  const sk = bundle.find((file) => file.path === "SKILL.md");
918
- const unverified = bundle.filter((file) => file.unverified).length;
925
+ const note2 = bundleNote(bundle, missing);
919
926
  return {
920
927
  ...meta,
921
928
  raw: sk ? sk.contents.toString("utf8") : skillMdFor(skill),
922
929
  files: bundle,
923
- ...unverified ? { note: unverifiedFilesNote(unverified) } : {}
930
+ ...note2 ? { note: note2 } : {}
924
931
  };
925
932
  }
926
933
  const pack = await resolvePackFiles(skill);
@@ -1010,13 +1017,14 @@ function makeDefaultDeps(flags) {
1010
1017
  for (let i = n++; i < multi.length; i = n++) {
1011
1018
  const c = multi[i];
1012
1019
  try {
1013
- const bundle = await fetchBundle(apiBase2, c.registrySlug, token2);
1020
+ const missing2 = [];
1021
+ const bundle = await fetchBundle(apiBase2, c.registrySlug, token2, { missing: missing2 });
1014
1022
  if (!bundle?.length) continue;
1015
1023
  const sk = bundle.find((file) => file.path === "SKILL.md");
1016
- const unverified = bundle.filter((file) => file.unverified).length;
1024
+ const note2 = bundleNote(bundle, missing2);
1017
1025
  c.files = bundle;
1018
1026
  if (sk) c.raw = sk.contents.toString("utf8");
1019
- if (unverified) c.note = unverifiedFilesNote(unverified);
1027
+ if (note2) c.note = note2;
1020
1028
  } catch {
1021
1029
  }
1022
1030
  }
package/dist/mcp.js CHANGED
@@ -8,11 +8,12 @@ import {
8
8
  fetchBundle,
9
9
  installSkill,
10
10
  looksLikeProject,
11
+ missingFilesNote,
11
12
  resolvePackFiles,
12
13
  safeText,
13
14
  stripTerminalEscapes,
14
15
  telemetryDisabled
15
- } from "./chunk-FVWCI37S.js";
16
+ } from "./chunk-6JVWN3IG.js";
16
17
 
17
18
  // src/mcp/server.ts
18
19
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -206,9 +207,11 @@ async function installFromRegistry(args, ctx, deps = {}) {
206
207
  let note = "";
207
208
  if (skill.type === "pack") {
208
209
  try {
209
- const bundle = await getBundle(ctx.base, `${owner}/${name}`, ctx.token);
210
+ const missing = [];
211
+ const bundle = await getBundle(ctx.base, `${owner}/${name}`, ctx.token, { missing });
210
212
  if (bundle?.length) {
211
213
  files = bundle.some((f) => f.path === "SKILL.md") ? bundle : [...bundle, { path: "SKILL.md", contents: raw }];
214
+ if (missing.length) note = missingFilesNote(missing);
212
215
  } else {
213
216
  const pack = await getPackFiles(skill);
214
217
  if (pack) {
@@ -549,7 +552,7 @@ async function startMcpServer() {
549
552
  name: "skillmd",
550
553
  version: VERSION,
551
554
  title: "SkillMD",
552
- description: "The open registry of Agent Skills: search, inspect, lint and install 25,000+ linted, security-reviewed SKILL.md files for Claude Code, Cursor, Codex and 60+ other agents.",
555
+ description: "The open registry of Agent Skills: search, inspect, lint and install 1,000,000+ linted, security-reviewed SKILL.md files for Claude Code, Cursor, Codex and 60+ other agents.",
553
556
  websiteUrl: "https://skillmd.com",
554
557
  icons: [
555
558
  { src: "https://skillmd.com/favicon.png", mimeType: "image/png", sizes: ["512x512"] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillmds",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "SkillMD for agents: the `skillmds` MCP server + the `skillmd` CLI (lint, scan, search, install, publish Agent Skills) from skillmd.com.",
5
5
  "license": "MIT",
6
6
  "author": "SkillMD",