promptgraph-mcp 2.3.2 → 2.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.
Files changed (2) hide show
  1. package/github-import.js +33 -9
  2. package/package.json +1 -1
package/github-import.js CHANGED
@@ -33,19 +33,42 @@ function repoExists(ownerRepo) {
33
33
  });
34
34
  }
35
35
 
36
- // Ask GitHub API which skill subdir exists (without cloning anything)
36
+ // Ask GitHub API which subdir to use (without cloning anything).
37
+ // Returns { subdir, label } or null (use root).
37
38
  async function detectSkillsDirFromAPI(ownerRepo) {
38
39
  try {
39
40
  const json = await httpsGet(`https://api.github.com/repos/${ownerRepo}/contents`);
40
41
  const entries = JSON.parse(json);
41
- const dirs = new Set(entries.filter(e => e.type === 'dir').map(e => e.name.toLowerCase()));
42
+
43
+ // 1. Known skill dir names (priority order)
44
+ const dirMap = new Map(entries.filter(e => e.type === 'dir').map(e => [e.name.toLowerCase(), e.name]));
42
45
  for (const d of SKILL_DIRS) {
43
- if (dirs.has(d)) return d;
46
+ if (dirMap.has(d)) return { subdir: dirMap.get(d), label: d };
47
+ }
48
+
49
+ // 2. Any subdir with 2+ .md files — pick the one with most .md files
50
+ const subdirCandidates = entries.filter(e => e.type === 'dir' && !SKIP_DIRS_API.has(e.name.toLowerCase()));
51
+ let best = null, bestCount = 0;
52
+ for (const dir of subdirCandidates) {
53
+ try {
54
+ const sub = await httpsGet(`https://api.github.com/repos/${ownerRepo}/contents/${dir.name}`);
55
+ const subEntries = JSON.parse(sub);
56
+ const mdCount = subEntries.filter(e => e.type === 'file' && e.name.endsWith('.md')).length;
57
+ if (mdCount >= 1 && mdCount > bestCount) { best = dir.name; bestCount = mdCount; }
58
+ } catch {}
44
59
  }
60
+ if (best) return { subdir: best, label: best };
61
+
45
62
  } catch {}
46
- return null; // use repo root
63
+ return null; // no good subdir found — use root
47
64
  }
48
65
 
66
+ const SKIP_DIRS_API = new Set([
67
+ '.github', 'docs', 'doc', 'documentation', 'examples', 'example',
68
+ 'tests', 'test', 'assets', 'images', 'img', 'media', 'static',
69
+ 'node_modules', 'vendor', 'dist', 'build', '.git',
70
+ ]);
71
+
49
72
  function git(args, cwd, stdio = 'inherit') {
50
73
  return spawnSync('git', args, { cwd, stdio });
51
74
  }
@@ -109,7 +132,7 @@ function detectSkillsDirLocal(repoRoot) {
109
132
  const candidate = path.join(repoRoot, dir);
110
133
  if (fs.existsSync(candidate)) {
111
134
  const files = globSync(`${candidate}/**/*.md`);
112
- if (files.length >= 2) return { dir: candidate, label: dir, sparse: true };
135
+ if (files.length >= 1) return { dir: candidate, label: dir, sparse: true };
113
136
  }
114
137
  }
115
138
  return { dir: repoRoot, label: '(root)', sparse: false };
@@ -142,21 +165,22 @@ export async function importFromGitHub(repoUrl) {
142
165
 
143
166
  if (isNew) {
144
167
  // Detect skills dir via API before cloning
145
- console.log(`Detecting skills directory for ${ownerRepo}...`);
146
- skillsSubdir = await detectSkillsDirFromAPI(ownerRepo);
168
+ process.stdout.write(`Detecting skills directory for ${ownerRepo}... `);
169
+ const detected = await detectSkillsDirFromAPI(ownerRepo);
170
+ skillsSubdir = detected?.subdir || null;
147
171
 
148
172
  if (skillsSubdir) {
173
+ console.log(`found: ${detected.label}/`);
149
174
  console.log(`Sparse-cloning ${url} (${skillsSubdir}/ only)...`);
150
175
  cloneOk = sparseClone(url, dest, skillsSubdir);
151
176
  if (!cloneOk) {
152
- // Sparse failed — fall back to full clone
153
177
  console.log('Sparse-checkout failed, falling back to full clone...');
154
178
  fs.rmSync(dest, { recursive: true, force: true });
155
179
  cloneOk = fullClone(url, dest);
156
180
  skillsSubdir = null;
157
181
  }
158
182
  } else {
159
- console.log(`Cloning ${url}...`);
183
+ console.log(`no subdir found, cloning root...`);
160
184
  cloneOk = fullClone(url, dest);
161
185
  }
162
186
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptgraph-mcp",
3
- "version": "2.3.2",
3
+ "version": "2.3.4",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "bin": {