promptgraph-mcp 2.4.0 → 2.4.1

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
@@ -4,7 +4,8 @@ import fs from 'fs';
4
4
  import https from 'https';
5
5
  import { globSync } from 'glob';
6
6
  import { indexAll, indexSource } from './indexer.js';
7
- import { loadConfig, saveConfig, SKILLS_STORE_DIR } from './config.js';
7
+ import { loadConfig, saveConfig, PROMPTGRAPH_DIR, SKILLS_STORE_DIR } from './config.js';
8
+ import { validateSkill } from './validator.js';
8
9
 
9
10
  const SKILL_DIRS = ['skills', 'commands', 'prompts', 'agents', 'skills-store', 'slash-commands', 'custom-commands', 'templates'];
10
11
 
@@ -33,6 +34,58 @@ function repoExists(ownerRepo) {
33
34
  });
34
35
  }
35
36
 
37
+ // Validate all .md files in a repo's skills subdir against validateSkill().
38
+ // Returns { ok, errors[], warnings[] }.
39
+ export async function validateRepoSkills(ownerRepo) {
40
+ const errors = [];
41
+ const warnings = [];
42
+
43
+ const detected = await detectSkillsDirFromAPI(ownerRepo);
44
+ if (!detected) {
45
+ return { ok: false, errors: [`No skills directory found in ${ownerRepo}`], warnings: [] };
46
+ }
47
+
48
+ const subdir = detected.subdir;
49
+ const listUrl = `https://api.github.com/repos/${ownerRepo}/contents/${subdir}`;
50
+ let entries;
51
+ try {
52
+ const json = await httpsGet(listUrl);
53
+ entries = JSON.parse(json);
54
+ } catch (e) {
55
+ return { ok: false, errors: [`Failed to list ${subdir}/ contents: ${e.message}`], warnings: [] };
56
+ }
57
+
58
+ const mdFiles = entries.filter(e => e.type === 'file' && e.name.endsWith('.md'));
59
+ if (mdFiles.length === 0) {
60
+ return { ok: false, errors: [`No .md files found in ${subdir}/`], warnings: [] };
61
+ }
62
+
63
+ const tmpDir = path.join(PROMPTGRAPH_DIR, '.validate-tmp');
64
+ fs.mkdirSync(tmpDir, { recursive: true });
65
+
66
+ for (const file of mdFiles) {
67
+ try {
68
+ const content = await httpsGet(file.download_url);
69
+ const tmpPath = path.join(tmpDir, file.name);
70
+ fs.writeFileSync(tmpPath, content);
71
+ const result = validateSkill(tmpPath);
72
+ if (!result.ok) {
73
+ errors.push(`${file.name}: ${result.errors.join('; ')}`);
74
+ }
75
+ if (result.warnings?.length) {
76
+ warnings.push(...result.warnings.map(w => `${file.name}: ${w}`));
77
+ }
78
+ fs.unlinkSync(tmpPath);
79
+ } catch (e) {
80
+ errors.push(`${file.name}: failed to validate — ${e.message}`);
81
+ }
82
+ }
83
+
84
+ try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch {}
85
+
86
+ return { ok: errors.length === 0, errors, warnings };
87
+ }
88
+
36
89
  // Ask GitHub API which subdir to use (without cloning anything). Exported for validation.
37
90
  export
38
91
  // Returns { subdir, label } or null (use root).
package/marketplace.js CHANGED
@@ -7,7 +7,7 @@ import { createRequire } from 'module';
7
7
  import { getDb } from './db.js';
8
8
  import { validateSkill, validateBundle } from './validator.js';
9
9
  import { loadConfig, saveConfig, PROMPTGRAPH_DIR, SKILLS_STORE_DIR } from './config.js';
10
- import { importFromGitHub } from './github-import.js';
10
+ import { importFromGitHub, validateRepoSkills } from './github-import.js';
11
11
 
12
12
  const REGISTRY_URL = 'https://raw.githubusercontent.com/NeiP4n/promptgraph-registry/main/registry.json';
13
13
  const SKILLS_DIR = path.join(SKILLS_STORE_DIR, 'marketplace');
@@ -316,6 +316,19 @@ export async function publishBundle(bundleDef) {
316
316
  return { error: 'Bundle validation failed', issues: validation.errors, warnings: validation.warnings };
317
317
  }
318
318
 
319
+ // Validate repo skills content if repo_url is set
320
+ if (def.repo_url) {
321
+ const ownerRepo = def.repo_url.replace(/^https?:\/\/github\.com\//, '').replace(/\.git$/, '');
322
+ const repoValidation = await validateRepoSkills(ownerRepo);
323
+ if (!repoValidation.ok) {
324
+ return {
325
+ error: 'Repo skills validation failed',
326
+ issues: repoValidation.errors,
327
+ warnings: repoValidation.warnings,
328
+ };
329
+ }
330
+ }
331
+
319
332
  const bundleJson = JSON.stringify(def, null, 2);
320
333
  const tmpFile = path.join(PROMPTGRAPH_DIR, `bundle-${def.id}.json`);
321
334
  fs.mkdirSync(PROMPTGRAPH_DIR, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "promptgraph-mcp",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,4 +51,4 @@
51
51
  "tar": "^6.2.1",
52
52
  "js-yaml": "^4.1.0"
53
53
  }
54
- }
54
+ }