promptgraph-mcp 2.3.7 → 2.3.9

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/github-import.js CHANGED
@@ -33,7 +33,8 @@ function repoExists(ownerRepo) {
33
33
  });
34
34
  }
35
35
 
36
- // Ask GitHub API which subdir to use (without cloning anything).
36
+ // Ask GitHub API which subdir to use (without cloning anything). Exported for validation.
37
+ export
37
38
  // Returns { subdir, label } or null (use root).
38
39
  async function detectSkillsDirFromAPI(ownerRepo) {
39
40
  try {
package/index.js CHANGED
@@ -449,6 +449,21 @@ if (args[0] === 'bundle') {
449
449
  const repoArg = doPush ? args[2] : args[2];
450
450
  if (!repoArg || !repoArg.includes('/')) { error('Usage: pg bundle add-repo <owner/repo> [--push]'); process.exit(1); }
451
451
  const repo = repoArg.replace('https://github.com/', '').replace('.git', '');
452
+
453
+ // Validate repo has a skill subdirectory before publishing
454
+ const { detectSkillsDirFromAPI: _detectDir } = await import('./github-import.js');
455
+ process.stdout.write(chalk.gray(` Checking ${repo} for skill subdirectory... `));
456
+ const detected = await _detectDir(repo);
457
+ if (!detected) {
458
+ console.log(chalk.red('none found'));
459
+ error(
460
+ `Cannot publish: no skill subdirectory found in ${repo}\n` +
461
+ ` Expected: skills/, prompts/, commands/, agents/, or any folder with .md files\n` +
462
+ ` Visit: https://github.com/${repo}`
463
+ );
464
+ process.exit(1);
465
+ }
466
+ console.log(chalk.green(`found: ${detected.label}/`));
452
467
  const name = repo.split('/')[1].replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
453
468
  const id = repo.replace('/', '-').toLowerCase();
454
469
  const bundle = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptgraph-mcp",
3
- "version": "2.3.7",
3
+ "version": "2.3.9",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "bin": {
package/parser.js CHANGED
@@ -18,8 +18,8 @@ const SKIP_FILENAMES = new Set([
18
18
  'pull_request_template', 'issue_template', 'funding',
19
19
  ]);
20
20
 
21
- // Filename patterns that are never skills
22
- const SKIP_FILENAME_RE = /^(_|\.)|^v?\d+[\.\-]\d+|^\d{4}[\-_]\d{2}|^readme|^license|^changelog|^contributing/i;
21
+ // Filename patterns that are never skills — readme* catches ALL variants (readme_de, readme_zh-CN, etc.)
22
+ const SKIP_FILENAME_RE = /^(_|\.)|^v?\d+[\.\-]\d+|^\d{4}[\-_]\d{2}|^readme|^license|^changelog|^contributing|^code.of.conduct|^security|^authors|^credits|^disclaimer|^notice|^copying|^warranty|^promotion|^funding/i;
23
23
 
24
24
  // Path segments that indicate the file is NOT a skill
25
25
  const SKIP_DIRS = new Set([
@@ -30,7 +30,7 @@ const SKIP_DIRS = new Set([
30
30
  ]);
31
31
 
32
32
  // First-header values that signal documentation, not a skill
33
- const DOC_FIRST_HEADERS = /^(overview|introduction|about|background|welcome|getting started|what is|why |table of contents|toc|foreword|preface)/i;
33
+ const DOC_FIRST_HEADERS = /^(overview|introduction|about|background|welcome|getting started|what is|why |table of contents|toc|foreword|preface|readme)/i;
34
34
 
35
35
  // Imperative verbs commonly found in skill headers
36
36
  const IMPERATIVE_HEADERS = /\b(run|use|apply|execute|check|debug|fix|create|add|remove|deploy|test|write|generate|analyze|review|refactor|optimize|configure|setup|install|scan|audit|validate|search|find|extract|parse)\b/i;
@@ -119,6 +119,12 @@ export function isSkillFile(filePath, raw) {
119
119
 
120
120
  try {
121
121
  if (!raw) raw = fs.readFileSync(filePath, 'utf8');
122
+
123
+ // Hard-reject: content starts with README header or badge lines
124
+ const firstLines = raw.trimStart().slice(0, 300);
125
+ if (/^#\s*readme\b/i.test(firstLines)) return false;
126
+ if (/!\[.*\]\(https?:\/\/(img\.shields\.io|badge\.fury|travis-ci|github\.com\/[^)]+\/badge)/i.test(firstLines)) return false;
127
+
122
128
  return skillScore(raw, base) >= 3;
123
129
  } catch {
124
130
  return false;