promptgraph-mcp 1.5.19 → 1.5.20

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.
Files changed (2) hide show
  1. package/marketplace.js +15 -5
  2. package/package.json +1 -1
package/marketplace.js CHANGED
@@ -2,6 +2,7 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import os from 'os';
4
4
  import https from 'https';
5
+ import { createHash } from 'crypto';
5
6
  import { spawnSync } from 'child_process';
6
7
  import { getDb } from './db.js';
7
8
  import { validateSkill } from './validator.js';
@@ -9,6 +10,12 @@ import { validateSkill } from './validator.js';
9
10
  const REGISTRY_URL = 'https://raw.githubusercontent.com/NeiP4n/promptgraph-registry/main/registry.json';
10
11
  const SKILLS_DIR = path.join(os.homedir(), '.claude', 'skills-store', 'marketplace');
11
12
 
13
+ // Deterministic short code from an id. Same id always yields the same code,
14
+ // so codes auto-generate — no need to assign them by hand.
15
+ export function codeFor(id) {
16
+ return 'pg-' + createHash('md5').update(String(id)).digest('hex').slice(0, 6);
17
+ }
18
+
12
19
  // Robust fetch: try undici fetch, fall back to node:https (works where undici fails on Windows)
13
20
  function httpGet(url) {
14
21
  return new Promise((resolve, reject) => {
@@ -44,6 +51,7 @@ export async function browseMarketplace(topK = 20) {
44
51
  const registry = JSON.parse(text);
45
52
  if (!Array.isArray(registry.skills)) return { error: 'Invalid registry format' };
46
53
  return registry.skills
54
+ .map(s => ({ ...s, code: s.code || codeFor(s.id) })) // auto-fill code
47
55
  .sort((a, b) => (b.stars || 0) - (a.stars || 0))
48
56
  .slice(0, topK);
49
57
  } catch (e) {
@@ -56,15 +64,16 @@ export async function installSkill(query) {
56
64
  const text = await fetchText(REGISTRY_URL);
57
65
  const registry = JSON.parse(text);
58
66
  const q = String(query).trim().toLowerCase();
59
- // match by code, id, or name (case-insensitive)
67
+ // match by code (stored OR auto-generated), id, or name
60
68
  const skill = registry.skills?.find(s =>
61
- s.code?.toLowerCase() === q ||
69
+ (s.code || codeFor(s.id)).toLowerCase() === q ||
62
70
  s.id?.toLowerCase() === q ||
63
71
  s.name?.toLowerCase() === q
64
72
  );
65
73
  if (!skill) {
66
- // maybe it's a bundle code/id hint the user
67
- const bundle = (registry.bundles || []).find(b => b.code?.toLowerCase() === q || b.id?.toLowerCase() === q);
74
+ const bundle = (registry.bundles || []).find(b =>
75
+ (b.code || codeFor(b.id)).toLowerCase() === q || b.id?.toLowerCase() === q
76
+ );
68
77
  if (bundle) return { error: `"${query}" is a bundle. Use pg_bundle_install("${bundle.id}") instead.` };
69
78
  return { error: `No skill matching "${query}" (try a code like pg-xxxxxx, an id, or a name)` };
70
79
  }
@@ -89,6 +98,7 @@ export async function browseBundles(topK = 20) {
89
98
  const registry = JSON.parse(text);
90
99
  const bundles = registry.bundles || [];
91
100
  return bundles
101
+ .map(b => ({ ...b, code: b.code || codeFor(b.id) }))
92
102
  .sort((a, b) => (b.stars || 0) - (a.stars || 0))
93
103
  .slice(0, topK);
94
104
  } catch (e) {
@@ -102,7 +112,7 @@ export async function installBundle(bundleId) {
102
112
  const registry = JSON.parse(text);
103
113
  const q = String(bundleId).trim().toLowerCase();
104
114
  const bundle = (registry.bundles || []).find(b =>
105
- b.code?.toLowerCase() === q || b.id?.toLowerCase() === q || b.name?.toLowerCase() === q
115
+ (b.code || codeFor(b.id)).toLowerCase() === q || b.id?.toLowerCase() === q || b.name?.toLowerCase() === q
106
116
  );
107
117
  if (!bundle) return { error: `No bundle matching "${bundleId}"` };
108
118
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptgraph-mcp",
3
- "version": "1.5.19",
3
+ "version": "1.5.20",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "bin": {