promptgraph-mcp 1.5.14 → 1.5.16
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/index.js +73 -5
- package/marketplace.js +42 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { startWatcher } from './watcher.js';
|
|
|
8
8
|
import { promptConfig } from './config.js';
|
|
9
9
|
import { importFromGitHub } from './github-import.js';
|
|
10
10
|
import { detectPlatforms, PLATFORMS } from './platform.js';
|
|
11
|
-
import { browseMarketplace, installSkill, publishSkill, getTopRated, recordUse, recordSuccess, recordFail } from './marketplace.js';
|
|
11
|
+
import { browseMarketplace, installSkill, publishSkill, getTopRated, recordUse, recordSuccess, recordFail, browseBundles, installBundle } from './marketplace.js';
|
|
12
12
|
|
|
13
13
|
import { colors, banner, success, error, info, section, table } from './cli.js';
|
|
14
14
|
import boxen from 'boxen';
|
|
@@ -83,6 +83,51 @@ if (args[0] === 'doctor') {
|
|
|
83
83
|
process.exit(0);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
if (args[0] === 'marketplace' && (args[1] === 'bundles' || args[1] === 'bundle')) {
|
|
87
|
+
const { browseBundles } = await import('./marketplace.js');
|
|
88
|
+
const purple = chalk.hex('#7C3AED');
|
|
89
|
+
const spin = (await import('./cli.js')).spinner('Fetching bundles...');
|
|
90
|
+
spin.start();
|
|
91
|
+
const bundles = await browseBundles(1000);
|
|
92
|
+
spin.stop();
|
|
93
|
+
|
|
94
|
+
if (bundles?.error) { error(bundles.error); process.exit(1); }
|
|
95
|
+
|
|
96
|
+
console.log();
|
|
97
|
+
console.log(' ' + purple.bold('PromptGraph Bundles') + chalk.gray(' curated skill sets'));
|
|
98
|
+
console.log(' ' + chalk.gray(`${bundles.length} bundle${bundles.length === 1 ? '' : 's'}`));
|
|
99
|
+
console.log(' ' + chalk.gray('─'.repeat(54)));
|
|
100
|
+
console.log();
|
|
101
|
+
|
|
102
|
+
if (!bundles.length) {
|
|
103
|
+
info('No bundles yet.');
|
|
104
|
+
console.log(chalk.gray(' github.com/NeiP4n/promptgraph-registry\n'));
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const wrapB = (t, w, ind) => {
|
|
109
|
+
const words = (t || '').split(/\s+/); const lines = []; let line = '';
|
|
110
|
+
for (const x of words) { if ((line + ' ' + x).trim().length > w) { lines.push(line.trim()); line = x; } else line += ' ' + x; }
|
|
111
|
+
if (line.trim()) lines.push(line.trim());
|
|
112
|
+
return lines.map(l => ind + chalk.gray(l)).join('\n');
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
bundles.forEach((b, i) => {
|
|
116
|
+
const stars = b.stars > 0 ? chalk.yellow('★ ' + b.stars) : chalk.gray('★ 0');
|
|
117
|
+
console.log(' ' + chalk.gray((i + 1) + '.') + ' ' + chalk.white.bold(b.id) + ' ' + stars + chalk.gray(' ' + (b.skills?.length || 0) + ' skills'));
|
|
118
|
+
console.log(wrapB(b.description, 64, ' '));
|
|
119
|
+
console.log(' ' + chalk.gray('includes: ') + chalk.gray((b.skills || []).join(', ')));
|
|
120
|
+
if (b.tags?.length) console.log(' ' + purple(b.tags.map(t => '#' + t).join(' ')));
|
|
121
|
+
console.log(' ' + chalk.gray('install: ') + chalk.cyan(`pg_bundle_install("${b.id}")`));
|
|
122
|
+
console.log();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
console.log(' ' + chalk.gray('─'.repeat(54)));
|
|
126
|
+
console.log(' ' + chalk.gray('Installs all skills in the set. Run ') + chalk.cyan(`${bin} marketplace`) + chalk.gray(' for single skills.'));
|
|
127
|
+
console.log();
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
130
|
+
|
|
86
131
|
if (args[0] === 'marketplace') {
|
|
87
132
|
const { browseMarketplace } = await import('./marketplace.js');
|
|
88
133
|
const PER_PAGE = 10;
|
|
@@ -123,7 +168,7 @@ if (args[0] === 'marketplace') {
|
|
|
123
168
|
console.log();
|
|
124
169
|
console.log(' ' + purple.bold('PromptGraph Marketplace'));
|
|
125
170
|
console.log(' ' + chalk.gray(`${all.length} skill${all.length === 1 ? '' : 's'} · page ${page}/${totalPages}`));
|
|
126
|
-
console.log(' ' + chalk.gray('─'.repeat(
|
|
171
|
+
console.log(' ' + chalk.gray('─'.repeat(54)));
|
|
127
172
|
console.log();
|
|
128
173
|
|
|
129
174
|
slice.forEach((s, i) => {
|
|
@@ -132,18 +177,25 @@ if (args[0] === 'marketplace') {
|
|
|
132
177
|
console.log(' ' + num + ' ' + chalk.white.bold(s.id) + ' ' + stars);
|
|
133
178
|
console.log(wrap(s.description, 64, ' '));
|
|
134
179
|
if (s.tags?.length) console.log(' ' + purple(s.tags.map(t => '#' + t).join(' ')));
|
|
135
|
-
console.log(' ' + chalk.gray('install:
|
|
180
|
+
console.log(' ' + chalk.gray('install: ') + chalk.cyan(`pg_marketplace_install("${s.id}")`));
|
|
181
|
+
console.log(' ' + chalk.gray('use: ') + chalk.cyan(`pg_search("${s.id}")`) + chalk.gray(' → read the file'));
|
|
136
182
|
console.log();
|
|
137
183
|
});
|
|
138
184
|
|
|
139
|
-
console.log(' ' + chalk.gray('─'.repeat(
|
|
185
|
+
console.log(' ' + chalk.gray('─'.repeat(54)));
|
|
140
186
|
if (totalPages > 1) {
|
|
141
187
|
const nav = [];
|
|
142
188
|
if (page > 1) nav.push(chalk.cyan(`${bin} marketplace ${page - 1}`) + chalk.gray(' ‹ prev'));
|
|
143
189
|
if (page < totalPages) nav.push(chalk.gray('next › ') + chalk.cyan(`${bin} marketplace ${page + 1}`));
|
|
144
190
|
console.log(' ' + nav.join(' '));
|
|
191
|
+
console.log();
|
|
145
192
|
}
|
|
146
|
-
console.log(' ' + chalk.gray('
|
|
193
|
+
console.log(' ' + chalk.gray('These run through your AI assistant via the PromptGraph MCP server:'));
|
|
194
|
+
console.log(' ' + chalk.cyan('pg_marketplace_install') + chalk.gray(' install a skill ') + chalk.gray('(or /pg-fetch <id>)'));
|
|
195
|
+
console.log(' ' + chalk.cyan('pg_marketplace_publish') + chalk.gray(' share your own ') + chalk.gray('(or /pg-publish <file>)'));
|
|
196
|
+
console.log(' ' + chalk.cyan('pg_search') + chalk.gray(' find & apply any installed skill'));
|
|
197
|
+
console.log();
|
|
198
|
+
console.log(' ' + chalk.gray('Browse curated sets: ') + chalk.cyan(`${bin} marketplace bundles`));
|
|
147
199
|
console.log();
|
|
148
200
|
process.exit(0);
|
|
149
201
|
}
|
|
@@ -310,6 +362,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
310
362
|
required: ['file_path'],
|
|
311
363
|
},
|
|
312
364
|
},
|
|
365
|
+
{
|
|
366
|
+
name: 'pg_bundle_browse',
|
|
367
|
+
description: 'Browse curated bundles (sets of related skills) from the marketplace.',
|
|
368
|
+
inputSchema: { type: 'object', properties: { top_k: { type: 'number' } } },
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: 'pg_bundle_install',
|
|
372
|
+
description: 'Install all skills in a bundle by bundle id.',
|
|
373
|
+
inputSchema: {
|
|
374
|
+
type: 'object',
|
|
375
|
+
properties: { bundle_id: { type: 'string' } },
|
|
376
|
+
required: ['bundle_id'],
|
|
377
|
+
},
|
|
378
|
+
},
|
|
313
379
|
],
|
|
314
380
|
}));
|
|
315
381
|
|
|
@@ -335,6 +401,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
335
401
|
case 'pg_marketplace_browse': result = await browseMarketplace(args.top_k || 20); break;
|
|
336
402
|
case 'pg_marketplace_install': result = await installSkill(args.skill_id); break;
|
|
337
403
|
case 'pg_marketplace_publish': result = await publishSkill(args.file_path); break;
|
|
404
|
+
case 'pg_bundle_browse': result = await browseBundles(args.top_k || 20); break;
|
|
405
|
+
case 'pg_bundle_install': result = await installBundle(args.bundle_id); break;
|
|
338
406
|
default: throw new Error(`Unknown tool: ${name}`);
|
|
339
407
|
}
|
|
340
408
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
package/marketplace.js
CHANGED
|
@@ -71,6 +71,48 @@ export async function installSkill(skillId) {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
export async function browseBundles(topK = 20) {
|
|
75
|
+
try {
|
|
76
|
+
const text = await fetchText(REGISTRY_URL);
|
|
77
|
+
const registry = JSON.parse(text);
|
|
78
|
+
const bundles = registry.bundles || [];
|
|
79
|
+
return bundles
|
|
80
|
+
.sort((a, b) => (b.stars || 0) - (a.stars || 0))
|
|
81
|
+
.slice(0, topK);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
return { error: `Registry unavailable: ${e.message}` };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export async function installBundle(bundleId) {
|
|
88
|
+
try {
|
|
89
|
+
const text = await fetchText(REGISTRY_URL);
|
|
90
|
+
const registry = JSON.parse(text);
|
|
91
|
+
const bundle = (registry.bundles || []).find(b => b.id === bundleId);
|
|
92
|
+
if (!bundle) return { error: `Bundle "${bundleId}" not found in registry` };
|
|
93
|
+
|
|
94
|
+
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
95
|
+
const installed = [];
|
|
96
|
+
const failed = [];
|
|
97
|
+
|
|
98
|
+
for (const skillId of bundle.skills || []) {
|
|
99
|
+
const skill = registry.skills?.find(s => s.id === skillId);
|
|
100
|
+
if (!skill?.raw_url) { failed.push(skillId); continue; }
|
|
101
|
+
try {
|
|
102
|
+
const content = await fetchText(skill.raw_url);
|
|
103
|
+
fs.writeFileSync(path.join(SKILLS_DIR, `${skillId}.md`), content);
|
|
104
|
+
installed.push(skillId);
|
|
105
|
+
} catch {
|
|
106
|
+
failed.push(skillId);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return { success: true, bundle: bundle.name, installed, failed, dir: SKILLS_DIR };
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return { error: e.message };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
74
116
|
export async function publishSkill(filePath) {
|
|
75
117
|
if (!fs.existsSync(filePath)) return { error: `File not found: ${filePath}` };
|
|
76
118
|
|