promptgraph-mcp 2.8.1 → 2.8.3

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/commands/init.js CHANGED
@@ -1,37 +1,37 @@
1
- import { colors, banner, success, error, info, section, table } from '../cli.js';
2
- import chalk from 'chalk';
3
- import boxen from 'boxen';
4
-
5
- export default async function handler(args, bin) {
6
- const { promptConfig } = await import('../config.js');
7
- const { indexAll } = await import('../indexer.js');
8
- const os = await import('os');
9
- const fs = await import('fs');
10
- const path = await import('path');
11
- const commandsDir = path.default.join(os.default.homedir(), '.claude', 'commands');
12
- if (!fs.default.existsSync(commandsDir)) {
13
- console.log(chalk.yellow('⚠') + ' ' + chalk.gray('~/.claude/commands/ not found — is Claude Code installed?'));
14
- console.log(chalk.gray(' Install from: https://claude.ai/download\n'));
15
- }
16
- if (!args.includes('--yes') && !args.includes('-y')) {
17
- const readline = await import('readline');
18
- const rl = readline.default.createInterface({ input: process.stdin, output: process.stdout });
19
- const answer = await new Promise(r => rl.question(
20
- chalk.yellow(' ⚠') + chalk.gray(' First run downloads ~23 MB embedding model (BGE-Small-EN).\n Proceed? [Y/n] '), r
21
- ));
22
- rl.close();
23
- if (answer.trim().toLowerCase() === 'n') { info('Aborted.'); process.exit(0); }
24
- }
25
- console.log(chalk.gray('\n Downloading embedding model (~23 MB, one-time)...\n'));
26
- const config = await promptConfig();
27
- await indexAll();
28
- console.log();
29
- console.log(
30
- boxen(
31
- chalk.white.bold('Add to Claude Code settings.json:') + '\n\n' +
32
- chalk.gray(JSON.stringify({ mcpServers: { promptgraph: { command: 'npx', args: ['promptgraph-mcp'] } } }, null, 2)),
33
- { padding: 1, borderStyle: 'round', borderColor: '#7C3AED', dimBorder: true }
34
- )
35
- );
36
- process.exit(0);
37
- }
1
+ import { colors, banner, success, error, info, section, table } from '../cli.js';
2
+ import chalk from 'chalk';
3
+ import boxen from 'boxen';
4
+
5
+ export default async function handler(args, bin) {
6
+ const { promptConfig } = await import('../config.js');
7
+ const { indexAll } = await import('../indexer.js');
8
+ const os = await import('os');
9
+ const fs = await import('fs');
10
+ const path = await import('path');
11
+ const commandsDir = path.default.join(os.default.homedir(), '.claude', 'commands');
12
+ if (!fs.default.existsSync(commandsDir)) {
13
+ console.log(chalk.yellow('⚠') + ' ' + chalk.gray('~/.claude/commands/ not found — is Claude Code installed?'));
14
+ console.log(chalk.gray(' Install from: https://claude.ai/download\n'));
15
+ }
16
+ if (!args.includes('--yes') && !args.includes('-y')) {
17
+ const readline = await import('readline');
18
+ const rl = readline.default.createInterface({ input: process.stdin, output: process.stdout });
19
+ const answer = await new Promise(r => rl.question(
20
+ chalk.yellow(' ⚠') + chalk.gray(' First run downloads ~23 MB embedding model (BGE-Small-EN).\n Proceed? [Y/n] '), r
21
+ ));
22
+ rl.close();
23
+ if (answer.trim().toLowerCase() === 'n') { info('Aborted.'); process.exit(0); }
24
+ }
25
+ console.log(chalk.gray('\n Downloading embedding model (~23 MB, one-time)...\n'));
26
+ const config = await promptConfig();
27
+ await indexAll();
28
+ console.log();
29
+ console.log(
30
+ boxen(
31
+ chalk.white.bold('Add to Claude Code settings.json:') + '\n\n' +
32
+ chalk.gray(JSON.stringify({ mcpServers: { promptgraph: { command: 'npx', args: ['promptgraph-mcp'] } } }, null, 2)),
33
+ { padding: 1, borderStyle: 'round', borderColor: '#7C3AED', dimBorder: true }
34
+ )
35
+ );
36
+ process.exit(0);
37
+ }
@@ -1,146 +1,146 @@
1
- import { colors, banner, success, error, info, section, table } from '../cli.js';
2
- import chalk from 'chalk';
3
- import path from 'path';
4
- import os from 'os';
5
- import fs from 'fs';
6
-
7
- export default async function handler(args, bin) {
8
- // Subcommand: validate / prune all installed marketplace files
9
- if (args[0] === 'validate' || args[0] === 'prune' || args[0] === '--validate' || args[0] === '--prune') {
10
- const { validateAndPruneMarketplace } = await import('../marketplace.js');
11
- const result = validateAndPruneMarketplace();
12
- if (result.removed.length > 0) {
13
- error(`Removed ${result.removed.length} invalid files:`);
14
- result.removed.forEach(r => console.log(` ${chalk.red('✗')} ${r.file}`));
15
- }
16
- if (result.errors.length > 0) {
17
- error(`${result.errors.length} errors:`);
18
- result.errors.forEach(e => console.log(` ${chalk.yellow('⚠')} ${e}`));
19
- }
20
- success(`${result.valid.length} valid files, ${result.removed.length} removed, ${result.errors.length} errors`);
21
- process.exit(result.errors.length > 0 ? 1 : 0);
22
- }
23
-
24
- if (!process.stdout.isTTY) {
25
- error('marketplace TUI requires an interactive terminal');
26
- process.exit(1);
27
- }
28
- const { browseMarketplace, browseBundles, installSkill, installBundle, installBundleBg, validateAndPruneMarketplace } = await import('../marketplace.js');
29
- const { loadConfig: _lcMkt } = await import('../config.js');
30
- const { getDb: _getDbMkt } = await import('../db.js');
31
- const { spinner: spin2 } = await import('../cli.js');
32
- const sp = spin2('Fetching marketplace...');
33
- sp.start();
34
- try {
35
- var [skills, bundles] = await Promise.all([browseMarketplace(1000), browseBundles(1000)]);
36
- } finally {
37
- sp.stop();
38
- }
39
-
40
- if (skills?.error) { error(skills.error); process.exit(1); }
41
-
42
- const { getCachedCount, refreshCountsInBackground } = await import('../bundle-counts.js');
43
- const bundlesWithCounts = (Array.isArray(bundles) ? bundles : []).map(b => {
44
- if (!b.repo_url) return b;
45
- const cached = getCachedCount(b.repo_url);
46
- return cached !== null ? { ...b, skillCount: cached } : b;
47
- });
48
- refreshCountsInBackground(bundlesWithCounts);
49
-
50
- const installedSet = new Set();
51
- try {
52
- const cfg = _lcMkt();
53
- const db = _getDbMkt();
54
- const { SKILLS_STORE_DIR } = await import('../config.js');
55
- const githubDir = path.join(SKILLS_STORE_DIR, 'github');
56
-
57
- for (const b of (Array.isArray(bundles) ? bundles : [])) {
58
- if (b.repo_url) {
59
- const owner = b.repo_url.split('/')[0];
60
- const repo = b.repo_url.split('/')[1];
61
- const clonedName = `${owner}-${repo}`;
62
- const clonedDir = path.join(githubDir, clonedName);
63
- const dirExists = fs.existsSync(clonedDir) &&
64
- fs.readdirSync(clonedDir).length > 0;
65
- if (dirExists) installedSet.add(b.id);
66
- } else if (Array.isArray(b.skills)) {
67
- const allOnDisk = b.skills.every(sid => {
68
- const row = db.prepare('SELECT path FROM skills WHERE id = ?').get(sid);
69
- return row && fs.existsSync(row.path);
70
- });
71
- if (b.skills.length > 0 && allOnDisk) installedSet.add(b.id);
72
- }
73
- }
74
-
75
- for (const row of db.prepare('SELECT id, path FROM skills WHERE source = ?').all('marketplace')) {
76
- if (fs.existsSync(row.path)) installedSet.add(row.id);
77
- }
78
- } catch {}
79
-
80
- const { runTUI } = await import('../tui.js');
81
- const { loadConfig: _lcR, saveConfig: _scR, SKILLS_STORE_DIR: _ssR } = await import('../config.js');
82
- const { getDb: _getDbR } = await import('../db.js');
83
-
84
- await runTUI(
85
- Array.isArray(skills) ? skills : [],
86
- bundlesWithCounts,
87
- async (item, onStatus) => {
88
- if (item.type === 'bundle') {
89
- const r = await installBundleBg(item.id, async (err, result) => {
90
- if (err) { onStatus(false, err.message?.slice(0, 60) || 'Install failed'); return; }
91
- installedSet.add(item.id);
92
- const { getCachedCount } = await import('../bundle-counts.js');
93
- const cached = getCachedCount(item.repo_url);
94
- if (cached !== null) item.skillCount = cached;
95
- validateAndPruneMarketplace();
96
- onStatus(true, `Installed ${item.name}`);
97
- });
98
- if (r?.error) {
99
- if (!r.dedup) onStatus(false, r.error.slice(0, 60));
100
- return;
101
- }
102
- onStatus(null, `Queued ${item.name}…`);
103
- } else {
104
- const r = await installSkill(item.code || item.id);
105
- if (r?.error) { onStatus(false, r.error.slice(0, 60)); return; }
106
- installedSet.add(item.id);
107
- if (item.code) installedSet.add(item.code);
108
- validateAndPruneMarketplace();
109
- onStatus(true, `Installed ${item.name}`);
110
- }
111
- },
112
- installedSet,
113
- async (item) => {
114
- const cfg = _lcR();
115
- const db = _getDbR();
116
- if (item.type === 'bundle' && item.repo_url) {
117
- const owner = item.repo_url.split('/')[0];
118
- const repo = item.repo_url.split('/')[1];
119
- const clonedName = `${owner}-${repo}`;
120
- const clonedDir = path.join(_ssR, 'github', clonedName);
121
- if (fs.existsSync(clonedDir)) fs.rmSync(clonedDir, { recursive: true, force: true });
122
- const src = `github:${clonedName}`;
123
- cfg.sources = cfg.sources.filter(s => s.source !== src && !s.dir.startsWith(clonedDir));
124
- _scR(cfg);
125
- db.prepare('DELETE FROM skills WHERE source = ?').run(src);
126
- db.prepare('DELETE FROM chunks WHERE skill_id NOT IN (SELECT id FROM skills)').run();
127
- } else if (item.type === 'bundle') {
128
- const mktDir = path.join(_ssR, 'marketplace');
129
- for (const sid of (item.skills || [])) {
130
- const row = db.prepare('SELECT path FROM skills WHERE id = ?').get(sid);
131
- if (row?.path && fs.existsSync(row.path)) fs.unlinkSync(row.path);
132
- db.prepare('DELETE FROM skills WHERE id = ?').run(sid);
133
- db.prepare('DELETE FROM chunks WHERE skill_id = ?').run(sid);
134
- }
135
- } else {
136
- const row = db.prepare('SELECT path FROM skills WHERE id = ?').get(item.id);
137
- if (row?.path && fs.existsSync(row.path)) fs.unlinkSync(row.path);
138
- db.prepare('DELETE FROM skills WHERE id = ?').run(item.id);
139
- db.prepare('DELETE FROM chunks WHERE skill_id = ?').run(item.id);
140
- }
141
- installedSet.delete(item.id);
142
- if (item.code) installedSet.delete(item.code);
143
- }
144
- );
145
- process.exit(0);
146
- }
1
+ import { colors, banner, success, error, info, section, table } from '../cli.js';
2
+ import chalk from 'chalk';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import fs from 'fs';
6
+
7
+ export default async function handler(args, bin) {
8
+ // Subcommand: validate / prune all installed marketplace files
9
+ if (args[0] === 'validate' || args[0] === 'prune' || args[0] === '--validate' || args[0] === '--prune') {
10
+ const { validateAndPruneMarketplace } = await import('../marketplace.js');
11
+ const result = validateAndPruneMarketplace();
12
+ if (result.removed.length > 0) {
13
+ error(`Removed ${result.removed.length} invalid files:`);
14
+ result.removed.forEach(r => console.log(` ${chalk.red('✗')} ${r.file}`));
15
+ }
16
+ if (result.errors.length > 0) {
17
+ error(`${result.errors.length} errors:`);
18
+ result.errors.forEach(e => console.log(` ${chalk.yellow('⚠')} ${e}`));
19
+ }
20
+ success(`${result.valid.length} valid files, ${result.removed.length} removed, ${result.errors.length} errors`);
21
+ process.exit(result.errors.length > 0 ? 1 : 0);
22
+ }
23
+
24
+ if (!process.stdout.isTTY) {
25
+ error('marketplace TUI requires an interactive terminal');
26
+ process.exit(1);
27
+ }
28
+ const { browseMarketplace, browseBundles, installSkill, installBundle, installBundleBg, validateAndPruneMarketplace } = await import('../marketplace.js');
29
+ const { loadConfig: _lcMkt } = await import('../config.js');
30
+ const { getDb: _getDbMkt } = await import('../db.js');
31
+ const { spinner: spin2 } = await import('../cli.js');
32
+ const sp = spin2('Fetching marketplace...');
33
+ sp.start();
34
+ try {
35
+ var [skills, bundles] = await Promise.all([browseMarketplace(1000), browseBundles(1000)]);
36
+ } finally {
37
+ sp.stop();
38
+ }
39
+
40
+ if (skills?.error) { error(skills.error); process.exit(1); }
41
+
42
+ const { getCachedCount, refreshCountsInBackground } = await import('../bundle-counts.js');
43
+ const bundlesWithCounts = (Array.isArray(bundles) ? bundles : []).map(b => {
44
+ if (!b.repo_url) return b;
45
+ const cached = getCachedCount(b.repo_url);
46
+ return cached !== null ? { ...b, skillCount: cached } : b;
47
+ });
48
+ refreshCountsInBackground(bundlesWithCounts);
49
+
50
+ const installedSet = new Set();
51
+ try {
52
+ const cfg = _lcMkt();
53
+ const db = _getDbMkt();
54
+ const { SKILLS_STORE_DIR } = await import('../config.js');
55
+ const githubDir = path.join(SKILLS_STORE_DIR, 'github');
56
+
57
+ for (const b of (Array.isArray(bundles) ? bundles : [])) {
58
+ if (b.repo_url) {
59
+ const owner = b.repo_url.split('/')[0];
60
+ const repo = b.repo_url.split('/')[1];
61
+ const clonedName = `${owner}-${repo}`;
62
+ const clonedDir = path.join(githubDir, clonedName);
63
+ const dirExists = fs.existsSync(clonedDir) &&
64
+ fs.readdirSync(clonedDir).length > 0;
65
+ if (dirExists) installedSet.add(b.id);
66
+ } else if (Array.isArray(b.skills)) {
67
+ const allOnDisk = b.skills.every(sid => {
68
+ const row = db.prepare('SELECT path FROM skills WHERE id = ?').get(sid);
69
+ return row && fs.existsSync(row.path);
70
+ });
71
+ if (b.skills.length > 0 && allOnDisk) installedSet.add(b.id);
72
+ }
73
+ }
74
+
75
+ for (const row of db.prepare('SELECT id, path FROM skills WHERE source = ?').all('marketplace')) {
76
+ if (fs.existsSync(row.path)) installedSet.add(row.id);
77
+ }
78
+ } catch {}
79
+
80
+ const { runTUI } = await import('../tui.js');
81
+ const { loadConfig: _lcR, saveConfig: _scR, SKILLS_STORE_DIR: _ssR } = await import('../config.js');
82
+ const { getDb: _getDbR } = await import('../db.js');
83
+
84
+ await runTUI(
85
+ Array.isArray(skills) ? skills : [],
86
+ bundlesWithCounts,
87
+ async (item, onStatus) => {
88
+ if (item.type === 'bundle') {
89
+ const r = await installBundleBg(item.id, async (err, result) => {
90
+ if (err) { onStatus(false, err.message?.slice(0, 60) || 'Install failed'); return; }
91
+ installedSet.add(item.id);
92
+ const { getCachedCount } = await import('../bundle-counts.js');
93
+ const cached = getCachedCount(item.repo_url);
94
+ if (cached !== null) item.skillCount = cached;
95
+ validateAndPruneMarketplace();
96
+ onStatus(true, `Installed ${item.name}`);
97
+ });
98
+ if (r?.error) {
99
+ if (!r.dedup) onStatus(false, r.error.slice(0, 60));
100
+ return;
101
+ }
102
+ onStatus(null, `Queued ${item.name}…`);
103
+ } else {
104
+ const r = await installSkill(item.code || item.id);
105
+ if (r?.error) { onStatus(false, r.error.slice(0, 60)); return; }
106
+ installedSet.add(item.id);
107
+ if (item.code) installedSet.add(item.code);
108
+ validateAndPruneMarketplace();
109
+ onStatus(true, `Installed ${item.name}`);
110
+ }
111
+ },
112
+ installedSet,
113
+ async (item) => {
114
+ const cfg = _lcR();
115
+ const db = _getDbR();
116
+ if (item.type === 'bundle' && item.repo_url) {
117
+ const owner = item.repo_url.split('/')[0];
118
+ const repo = item.repo_url.split('/')[1];
119
+ const clonedName = `${owner}-${repo}`;
120
+ const clonedDir = path.join(_ssR, 'github', clonedName);
121
+ if (fs.existsSync(clonedDir)) fs.rmSync(clonedDir, { recursive: true, force: true });
122
+ const src = `github:${clonedName}`;
123
+ cfg.sources = cfg.sources.filter(s => s.source !== src && !s.dir.startsWith(clonedDir));
124
+ _scR(cfg);
125
+ db.prepare('DELETE FROM skills WHERE source = ?').run(src);
126
+ db.prepare('DELETE FROM chunks WHERE skill_id NOT IN (SELECT id FROM skills)').run();
127
+ } else if (item.type === 'bundle') {
128
+ const mktDir = path.join(_ssR, 'marketplace');
129
+ for (const sid of (item.skills || [])) {
130
+ const row = db.prepare('SELECT path FROM skills WHERE id = ?').get(sid);
131
+ if (row?.path && fs.existsSync(row.path)) fs.unlinkSync(row.path);
132
+ db.prepare('DELETE FROM skills WHERE id = ?').run(sid);
133
+ db.prepare('DELETE FROM chunks WHERE skill_id = ?').run(sid);
134
+ }
135
+ } else {
136
+ const row = db.prepare('SELECT path FROM skills WHERE id = ?').get(item.id);
137
+ if (row?.path && fs.existsSync(row.path)) fs.unlinkSync(row.path);
138
+ db.prepare('DELETE FROM skills WHERE id = ?').run(item.id);
139
+ db.prepare('DELETE FROM chunks WHERE skill_id = ?').run(item.id);
140
+ }
141
+ installedSet.delete(item.id);
142
+ if (item.code) installedSet.delete(item.code);
143
+ }
144
+ );
145
+ process.exit(0);
146
+ }
@@ -1,10 +1,10 @@
1
- import { colors, banner, success, error, info, section, table } from '../cli.js';
2
- import chalk from 'chalk';
3
-
4
- export default async function handler(args, bin) {
5
- const { indexAll } = await import('../indexer.js');
6
- const fast = args.includes('--fast');
7
- if (fast) info(chalk.yellow('Fast mode — skipping embeddings (keyword search only)'));
8
- await indexAll({ fast });
9
- process.exit(0);
10
- }
1
+ import { colors, banner, success, error, info, section, table } from '../cli.js';
2
+ import chalk from 'chalk';
3
+
4
+ export default async function handler(args, bin) {
5
+ const { indexAll } = await import('../indexer.js');
6
+ const fast = args.includes('--fast');
7
+ if (fast) info(chalk.yellow('Fast mode — skipping embeddings (keyword search only)'));
8
+ await indexAll({ fast });
9
+ process.exit(0);
10
+ }
@@ -1,55 +1,55 @@
1
- import { colors, banner, success, error, info, section, table } from '../cli.js';
2
- import chalk from 'chalk';
3
- import { VALID_TRUST_LEVELS, TRUST_LEVEL_BOOST } from '../marketplace.js';
4
-
5
- export default async function handler(args, bin) {
6
- const trustFilter = args.find(a => a.startsWith('--trust='));
7
- const filteredArgs = args.filter(a => !a.startsWith('--trust='));
8
- const query = filteredArgs.slice(1).join(' ');
9
- if (!query) { error('Usage: ' + bin + ' search <query> [--trust=verified]'); process.exit(1); }
10
-
11
- if (trustFilter) {
12
- const level = trustFilter.split('=')[1];
13
- if (!VALID_TRUST_LEVELS.includes(level)) {
14
- error('Invalid trust level. Valid: ' + VALID_TRUST_LEVELS.join(', '));
15
- process.exit(1);
16
- }
17
- }
18
-
19
- const { search: searchSkills } = await import('../search.js');
20
- const { getDb } = await import('../db.js');
21
- const { getByTrustLevel } = await import('../marketplace.js');
22
- const spin = (await import('../cli.js')).spinner('Searching...');
23
- spin.start();
24
- let results = await searchSkills(query, 10);
25
- spin.stop();
26
-
27
- // Apply trust filter after search
28
- if (trustFilter) {
29
- const level = trustFilter.split('=')[1];
30
- const entries = await getByTrustLevel(level);
31
- const allowed = new Set(entries.map(e => e.id));
32
- results = results.filter(r => allowed.has(r.id));
33
- }
34
-
35
- // Enrich results with trust level
36
- const db = getDb();
37
- const enriched = results.map(s => {
38
- const re = db.prepare('SELECT trust_level FROM registry_entries WHERE id = ?').get(s.id);
39
- return { ...s, trustLevel: re ? re.trust_level : 'unknown' };
40
- });
41
-
42
- if (!enriched.length) { info('No results for: ' + query); process.exit(0); }
43
- const purple = chalk.hex('#7C3AED');
44
- console.log();
45
- enriched.forEach((s, i) => {
46
- const score = chalk.dim((s.score * 100).toFixed(0) + '%');
47
- const trustBadge = s.trustLevel !== 'unknown' && s.trustLevel !== 'community'
48
- ? ' ' + purple(s.trustLevel) : '';
49
- console.log(' ' + chalk.dim(String(i + 1) + '.') + ' ' + chalk.bold.white(s.name) + trustBadge + ' ' + score);
50
- console.log(' ' + chalk.dim(s.description || ''));
51
- console.log(' ' + purple(s.source) + ' ' + chalk.dim(s.path));
52
- console.log();
53
- });
54
- process.exit(0);
55
- }
1
+ import { colors, banner, success, error, info, section, table } from '../cli.js';
2
+ import chalk from 'chalk';
3
+ import { VALID_TRUST_LEVELS, TRUST_LEVEL_BOOST } from '../marketplace.js';
4
+
5
+ export default async function handler(args, bin) {
6
+ const trustFilter = args.find(a => a.startsWith('--trust='));
7
+ const filteredArgs = args.filter(a => !a.startsWith('--trust='));
8
+ const query = filteredArgs.slice(1).join(' ');
9
+ if (!query) { error('Usage: ' + bin + ' search <query> [--trust=verified]'); process.exit(1); }
10
+
11
+ if (trustFilter) {
12
+ const level = trustFilter.split('=')[1];
13
+ if (!VALID_TRUST_LEVELS.includes(level)) {
14
+ error('Invalid trust level. Valid: ' + VALID_TRUST_LEVELS.join(', '));
15
+ process.exit(1);
16
+ }
17
+ }
18
+
19
+ const { search: searchSkills } = await import('../search.js');
20
+ const { getDb } = await import('../db.js');
21
+ const { getByTrustLevel } = await import('../marketplace.js');
22
+ const spin = (await import('../cli.js')).spinner('Searching...');
23
+ spin.start();
24
+ let results = await searchSkills(query, 10);
25
+ spin.stop();
26
+
27
+ // Apply trust filter after search
28
+ if (trustFilter) {
29
+ const level = trustFilter.split('=')[1];
30
+ const entries = await getByTrustLevel(level);
31
+ const allowed = new Set(entries.map(e => e.id));
32
+ results = results.filter(r => allowed.has(r.id));
33
+ }
34
+
35
+ // Enrich results with trust level
36
+ const db = getDb();
37
+ const enriched = results.map(s => {
38
+ const re = db.prepare('SELECT trust_level FROM registry_entries WHERE id = ?').get(s.id);
39
+ return { ...s, trustLevel: re ? re.trust_level : 'unknown' };
40
+ });
41
+
42
+ if (!enriched.length) { info('No results for: ' + query); process.exit(0); }
43
+ const purple = chalk.hex('#7C3AED');
44
+ console.log();
45
+ enriched.forEach((s, i) => {
46
+ const score = chalk.dim((s.score * 100).toFixed(0) + '%');
47
+ const trustBadge = s.trustLevel !== 'unknown' && s.trustLevel !== 'community'
48
+ ? ' ' + purple(s.trustLevel) : '';
49
+ console.log(' ' + chalk.dim(String(i + 1) + '.') + ' ' + chalk.bold.white(s.name) + trustBadge + ' ' + score);
50
+ console.log(' ' + chalk.dim(s.description || ''));
51
+ console.log(' ' + purple(s.source) + ' ' + chalk.dim(s.path));
52
+ console.log();
53
+ });
54
+ process.exit(0);
55
+ }
package/commands/setup.js CHANGED
@@ -1,19 +1,19 @@
1
- import { colors, banner, success, error, info, section, table } from '../cli.js';
2
- import chalk from 'chalk';
3
-
4
- export default async function handler(args, bin) {
5
- const { detectPlatforms, PLATFORMS } = await import('../platform.js');
6
- const platformId = args[1];
7
- if (!platformId) {
8
- section('Detected platforms');
9
- detectPlatforms().forEach(p => info(`${chalk.white(p.id.padEnd(16))} ${chalk.gray(p.name)}`));
10
- console.log(chalk.gray('\n Usage: promptgraph-mcp setup <platform-id>\n'));
11
- } else {
12
- const platform = PLATFORMS[platformId];
13
- if (!platform) { error(`Unknown platform: ${platformId}`); process.exit(1); }
14
- platform.addMcp(platform);
15
- success(`Registered in ${chalk.white(platform.name)}`);
16
- info(chalk.gray(platform.configPath));
17
- }
18
- process.exit(0);
19
- }
1
+ import { colors, banner, success, error, info, section, table } from '../cli.js';
2
+ import chalk from 'chalk';
3
+
4
+ export default async function handler(args, bin) {
5
+ const { detectPlatforms, PLATFORMS } = await import('../platform.js');
6
+ const platformId = args[1];
7
+ if (!platformId) {
8
+ section('Detected platforms');
9
+ detectPlatforms().forEach(p => info(`${chalk.white(p.id.padEnd(16))} ${chalk.gray(p.name)}`));
10
+ console.log(chalk.gray('\n Usage: promptgraph-mcp setup <platform-id>\n'));
11
+ } else {
12
+ const platform = PLATFORMS[platformId];
13
+ if (!platform) { error(`Unknown platform: ${platformId}`); process.exit(1); }
14
+ platform.addMcp(platform);
15
+ success(`Registered in ${chalk.white(platform.name)}`);
16
+ info(chalk.gray(platform.configPath));
17
+ }
18
+ process.exit(0);
19
+ }