promptgraph-mcp 1.5.17 → 1.5.19
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/cli.js +5 -0
- package/index.js +28 -25
- package/marketplace.js +21 -6
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -34,6 +34,11 @@ export function spinner(text) {
|
|
|
34
34
|
return ora({ text: colors.muted(text), spinner: 'dots', color: 'magenta' });
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// Full clear including scrollback (console.clear leaves scrollback on Windows)
|
|
38
|
+
export function clearScreen() {
|
|
39
|
+
process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
export function success(msg) {
|
|
38
43
|
console.log('\n' + colors.success('✓') + ' ' + msg);
|
|
39
44
|
}
|
package/index.js
CHANGED
|
@@ -90,7 +90,7 @@ if (args[0] === 'marketplace' && (args[1] === 'bundles' || args[1] === 'bundle')
|
|
|
90
90
|
spin.start();
|
|
91
91
|
const bundles = await browseBundles(1000);
|
|
92
92
|
spin.stop();
|
|
93
|
-
|
|
93
|
+
(await import('./cli.js')).clearScreen();
|
|
94
94
|
|
|
95
95
|
if (bundles?.error) { error(bundles.error); process.exit(1); }
|
|
96
96
|
|
|
@@ -134,11 +134,12 @@ if (args[0] === 'marketplace') {
|
|
|
134
134
|
const PER_PAGE = 10;
|
|
135
135
|
const page = Math.max(1, parseInt(args[1]) || 1);
|
|
136
136
|
|
|
137
|
+
const { clearScreen } = await import('./cli.js');
|
|
137
138
|
const spin = (await import('./cli.js')).spinner('Fetching registry...');
|
|
138
139
|
spin.start();
|
|
139
140
|
const all = await browseMarketplace(1000);
|
|
140
141
|
spin.stop();
|
|
141
|
-
|
|
142
|
+
clearScreen();
|
|
142
143
|
|
|
143
144
|
if (all?.error) {
|
|
144
145
|
error(all.error);
|
|
@@ -154,6 +155,7 @@ if (args[0] === 'marketplace') {
|
|
|
154
155
|
const startIdx = (page - 1) * PER_PAGE;
|
|
155
156
|
const slice = all.slice(startIdx, startIdx + PER_PAGE);
|
|
156
157
|
const purple = chalk.hex('#7C3AED');
|
|
158
|
+
const W = 60;
|
|
157
159
|
|
|
158
160
|
const wrap = (text, width, indent) => {
|
|
159
161
|
const words = (text || '').split(/\s+/);
|
|
@@ -164,40 +166,41 @@ if (args[0] === 'marketplace') {
|
|
|
164
166
|
else line += ' ' + w;
|
|
165
167
|
}
|
|
166
168
|
if (line.trim()) lines.push(line.trim());
|
|
167
|
-
return lines.map(l => indent + chalk.
|
|
169
|
+
return lines.map(l => indent + chalk.dim(l)).join('\n');
|
|
168
170
|
};
|
|
169
171
|
|
|
172
|
+
// header
|
|
170
173
|
console.log();
|
|
171
|
-
console.log(' ' + purple.bold('PromptGraph
|
|
172
|
-
console.log(' ' + chalk.
|
|
173
|
-
console.log(' ' +
|
|
174
|
-
console.log();
|
|
174
|
+
console.log(' ' + purple.bold('◆ PromptGraph') + chalk.dim(' · marketplace'));
|
|
175
|
+
console.log(' ' + chalk.dim(`${all.length} skills`) + chalk.dim(totalPages > 1 ? ` · page ${page}/${totalPages}` : ''));
|
|
176
|
+
console.log(chalk.dim(' ' + '━'.repeat(W)));
|
|
175
177
|
|
|
176
178
|
slice.forEach((s, i) => {
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
console.log(wrap(s.description, 64, ' '));
|
|
181
|
-
if (s.tags?.length) console.log(' ' + purple(s.tags.map(t => '#' + t).join(' ')));
|
|
182
|
-
console.log(' ' + chalk.gray('install: ') + chalk.cyan(`pg_marketplace_install("${s.id}")`));
|
|
183
|
-
console.log(' ' + chalk.gray('use: ') + chalk.cyan(`pg_search("${s.id}")`) + chalk.gray(' → read the file'));
|
|
179
|
+
const n = chalk.dim(String(startIdx + i + 1).padStart(2));
|
|
180
|
+
const code = s.code ? chalk.hex('#A78BFA')(s.code) : '';
|
|
181
|
+
const stars = chalk.yellow('★') + chalk.dim(' ' + (s.stars || 0));
|
|
184
182
|
console.log();
|
|
183
|
+
// line 1: number, name ........ code, stars
|
|
184
|
+
const left = `${n} ${chalk.bold.white(s.id)}`;
|
|
185
|
+
console.log(' ' + left + ' ' + code + ' ' + stars);
|
|
186
|
+
// description
|
|
187
|
+
console.log(wrap(s.description, W - 6, ' '));
|
|
188
|
+
// tags
|
|
189
|
+
if (s.tags?.length) console.log(' ' + chalk.dim(s.tags.map(t => '#' + t).join(' ')));
|
|
185
190
|
});
|
|
186
191
|
|
|
187
|
-
console.log(
|
|
192
|
+
console.log();
|
|
193
|
+
console.log(chalk.dim(' ' + '━'.repeat(W)));
|
|
194
|
+
|
|
188
195
|
if (totalPages > 1) {
|
|
189
196
|
const nav = [];
|
|
190
|
-
if (page > 1) nav.push(chalk.cyan(`${bin} marketplace ${page - 1}`)
|
|
191
|
-
if (page < totalPages) nav.push(chalk.
|
|
192
|
-
console.log(' ' + nav.join('
|
|
193
|
-
console.log();
|
|
197
|
+
if (page > 1) nav.push(chalk.dim('‹ ') + chalk.cyan(`${bin} marketplace ${page - 1}`));
|
|
198
|
+
if (page < totalPages) nav.push(chalk.cyan(`${bin} marketplace ${page + 1}`) + chalk.dim(' ›'));
|
|
199
|
+
console.log(' ' + nav.join(' '));
|
|
194
200
|
}
|
|
195
|
-
console.log(' ' + chalk.
|
|
196
|
-
console.log('
|
|
197
|
-
console.log('
|
|
198
|
-
console.log(' ' + chalk.cyan('pg_search') + chalk.gray(' find & apply any installed skill'));
|
|
199
|
-
console.log();
|
|
200
|
-
console.log(' ' + chalk.gray('Browse curated sets: ') + chalk.cyan(`${bin} marketplace bundles`));
|
|
201
|
+
console.log(' ' + chalk.dim('install ') + chalk.cyan('tell your AI:') + ' ' + chalk.white('install ') + chalk.hex('#A78BFA')(slice[0].code || slice[0].id));
|
|
202
|
+
console.log(' ' + chalk.dim('bundles ') + chalk.cyan(`${bin} marketplace bundles`));
|
|
203
|
+
console.log(' ' + chalk.dim('publish ') + chalk.cyan('tell your AI:') + ' ' + chalk.white('/pg-publish <file>'));
|
|
201
204
|
console.log();
|
|
202
205
|
process.exit(0);
|
|
203
206
|
}
|
package/marketplace.js
CHANGED
|
@@ -51,13 +51,25 @@ export async function browseMarketplace(topK = 20) {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export async function installSkill(
|
|
54
|
+
export async function installSkill(query) {
|
|
55
55
|
try {
|
|
56
56
|
const text = await fetchText(REGISTRY_URL);
|
|
57
57
|
const registry = JSON.parse(text);
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const q = String(query).trim().toLowerCase();
|
|
59
|
+
// match by code, id, or name (case-insensitive)
|
|
60
|
+
const skill = registry.skills?.find(s =>
|
|
61
|
+
s.code?.toLowerCase() === q ||
|
|
62
|
+
s.id?.toLowerCase() === q ||
|
|
63
|
+
s.name?.toLowerCase() === q
|
|
64
|
+
);
|
|
65
|
+
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);
|
|
68
|
+
if (bundle) return { error: `"${query}" is a bundle. Use pg_bundle_install("${bundle.id}") instead.` };
|
|
69
|
+
return { error: `No skill matching "${query}" (try a code like pg-xxxxxx, an id, or a name)` };
|
|
70
|
+
}
|
|
71
|
+
if (!skill.raw_url) return { error: `Skill "${skill.id}" has no download URL` };
|
|
72
|
+
const skillId = skill.id;
|
|
61
73
|
|
|
62
74
|
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
63
75
|
const dest = path.join(SKILLS_DIR, `${skillId}.md`);
|
|
@@ -88,8 +100,11 @@ export async function installBundle(bundleId) {
|
|
|
88
100
|
try {
|
|
89
101
|
const text = await fetchText(REGISTRY_URL);
|
|
90
102
|
const registry = JSON.parse(text);
|
|
91
|
-
const
|
|
92
|
-
|
|
103
|
+
const q = String(bundleId).trim().toLowerCase();
|
|
104
|
+
const bundle = (registry.bundles || []).find(b =>
|
|
105
|
+
b.code?.toLowerCase() === q || b.id?.toLowerCase() === q || b.name?.toLowerCase() === q
|
|
106
|
+
);
|
|
107
|
+
if (!bundle) return { error: `No bundle matching "${bundleId}"` };
|
|
93
108
|
|
|
94
109
|
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
95
110
|
const installed = [];
|