proofscan 0.10.8 → 0.10.10

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.
Files changed (41) hide show
  1. package/dist/cli.js +8 -2
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/catalog.d.ts +16 -0
  4. package/dist/commands/catalog.d.ts.map +1 -0
  5. package/dist/commands/catalog.js +568 -0
  6. package/dist/commands/catalog.js.map +1 -0
  7. package/dist/commands/index.d.ts +1 -0
  8. package/dist/commands/index.d.ts.map +1 -1
  9. package/dist/commands/index.js +2 -0
  10. package/dist/commands/index.js.map +1 -1
  11. package/dist/commands/scan.d.ts.map +1 -1
  12. package/dist/commands/scan.js +1 -17
  13. package/dist/commands/scan.js.map +1 -1
  14. package/dist/registry/client.d.ts +97 -0
  15. package/dist/registry/client.d.ts.map +1 -0
  16. package/dist/registry/client.js +227 -0
  17. package/dist/registry/client.js.map +1 -0
  18. package/dist/registry/index.d.ts +6 -0
  19. package/dist/registry/index.d.ts.map +1 -0
  20. package/dist/registry/index.js +6 -0
  21. package/dist/registry/index.js.map +1 -0
  22. package/dist/registry/sources.d.ts +60 -0
  23. package/dist/registry/sources.d.ts.map +1 -0
  24. package/dist/registry/sources.js +81 -0
  25. package/dist/registry/sources.js.map +1 -0
  26. package/dist/shell/popl-commands.d.ts.map +1 -1
  27. package/dist/shell/popl-commands.js +20 -3
  28. package/dist/shell/popl-commands.js.map +1 -1
  29. package/dist/shell/ref-commands.d.ts.map +1 -1
  30. package/dist/shell/ref-commands.js +28 -0
  31. package/dist/shell/ref-commands.js.map +1 -1
  32. package/dist/shell/tool-commands.d.ts.map +1 -1
  33. package/dist/shell/tool-commands.js +12 -0
  34. package/dist/shell/tool-commands.js.map +1 -1
  35. package/dist/shell/types.d.ts.map +1 -1
  36. package/dist/shell/types.js +12 -0
  37. package/dist/shell/types.js.map +1 -1
  38. package/dist/types/config.d.ts +9 -0
  39. package/dist/types/config.d.ts.map +1 -1
  40. package/dist/types/config.js.map +1 -1
  41. package/package.json +4 -1
package/dist/cli.js CHANGED
@@ -25,7 +25,7 @@ import { setOutputOptions } from './utils/output.js';
25
25
  const require = createRequire(import.meta.url);
26
26
  const packageJson = require('../package.json');
27
27
  const VERSION = packageJson.version;
28
- import { createConfigCommand, createConnectorsCommand, createScanCommand, createMonitorCommand, createSessionsCommand, createArchiveCommand, createViewCommand, createTreeCommand, createExploreCommand, createStatusCommand, createEventsCommand, createRpcCommand, createSummaryCommand, createPermissionsCommand, createRecordCommand, createDoctorCommand, createShellCommand, createSecretsCommand, createToolCommand, createProxyCommand, createLogCommand, createPoplCommand, } from './commands/index.js';
28
+ import { createConfigCommand, createConnectorsCommand, createScanCommand, createMonitorCommand, createSessionsCommand, createArchiveCommand, createViewCommand, createTreeCommand, createExploreCommand, createStatusCommand, createEventsCommand, createRpcCommand, createSummaryCommand, createPermissionsCommand, createRecordCommand, createDoctorCommand, createShellCommand, createSecretsCommand, createToolCommand, createProxyCommand, createLogCommand, createPoplCommand, createCatalogCommand, } from './commands/index.js';
29
29
  const program = new Command();
30
30
  // Global state for config path
31
31
  let globalConfigPath;
@@ -178,6 +178,12 @@ program.addCommand(createProxyCommand(getConfigPath));
178
178
  program.addCommand(createLogCommand(getConfigPath));
179
179
  // popl (Phase 6.0: Public Observable Proof Ledger)
180
180
  program.addCommand(createPoplCommand(getConfigPath));
181
+ // catalog (Phase 7.0: MCP Registry)
182
+ program.addCommand(createCatalogCommand(getConfigPath));
183
+ // Alias: cat = catalog
184
+ const catCmd = createCatalogCommand(getConfigPath);
185
+ catCmd.name('cat').description('Alias for catalog');
186
+ program.addCommand(catCmd);
181
187
  // ============================================================
182
188
  // Default action: pfscan → pfscan view
183
189
  // ============================================================
@@ -189,7 +195,7 @@ function hasHelpFlag() {
189
195
  const KNOWN_COMMANDS = new Set([
190
196
  'view', 'v', 'tree', 't', 'explore', 'e', 'status', 'st',
191
197
  'scan', 's', 'archive', 'a', 'config', 'c',
192
- 'connectors', 'connector', 'sessions', 'monitor', 'events', 'rpc', 'summary', 'permissions', 'record', 'doctor', 'shell', 'secrets', 'secret', 'tool', 'proxy', 'log', 'popl', 'help'
198
+ 'connectors', 'connector', 'sessions', 'monitor', 'events', 'rpc', 'summary', 'permissions', 'record', 'doctor', 'shell', 'secrets', 'secret', 'tool', 'proxy', 'log', 'popl', 'catalog', 'cat', 'help'
193
199
  ]);
194
200
  // Shell-only commands (not available as CLI commands)
195
201
  const SHELL_ONLY_COMMANDS = new Set(['send']);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Catalog command - MCP Registry operations
3
+ *
4
+ * pfscan catalog search <query> # Search servers by name/description
5
+ * pfscan catalog search <query> --all # Cross-source search
6
+ * pfscan catalog view <server> [field] # View server details or specific field
7
+ * pfscan catalog sources # Show available catalog sources
8
+ * pfscan catalog sources list # Same as sources
9
+ * pfscan catalog sources set <name> # Set default catalog source
10
+ *
11
+ * Provides access to the MCP server registry for discovering and inspecting
12
+ * available MCP servers.
13
+ */
14
+ import { Command } from 'commander';
15
+ export declare function createCatalogCommand(getConfigPath: () => string): Command;
16
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuZpC,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,MAAM,GAAG,OAAO,CAwQzE"}
@@ -0,0 +1,568 @@
1
+ /**
2
+ * Catalog command - MCP Registry operations
3
+ *
4
+ * pfscan catalog search <query> # Search servers by name/description
5
+ * pfscan catalog search <query> --all # Cross-source search
6
+ * pfscan catalog view <server> [field] # View server details or specific field
7
+ * pfscan catalog sources # Show available catalog sources
8
+ * pfscan catalog sources list # Same as sources
9
+ * pfscan catalog sources set <name> # Set default catalog source
10
+ *
11
+ * Provides access to the MCP server registry for discovering and inspecting
12
+ * available MCP servers.
13
+ */
14
+ import { Command } from 'commander';
15
+ import ora from 'ora';
16
+ import { RegistryClient, RegistryError, SUPPORTED_FIELDS, isSupportedField, getFieldValue, formatFieldValue, CATALOG_SOURCES, DEFAULT_CATALOG_SOURCE, getSource, isValidSource, getSourceNames, isSourceReady, getAuthErrorMessage, formatSourceLine, } from '../registry/index.js';
17
+ import { ConfigManager } from '../config/index.js';
18
+ import { output, getOutputOptions, outputSuccess, outputError } from '../utils/output.js';
19
+ /** Braille spinner frames */
20
+ const BRAILLE_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
21
+ /** Terminal width for formatting (fallback to 80) */
22
+ const TERM_WIDTH = process.stdout.columns || 80;
23
+ /**
24
+ * Check if we should show spinner
25
+ * - Only in TTY
26
+ * - Not in --json mode
27
+ * - Not in --verbose mode
28
+ */
29
+ function shouldShowSpinner() {
30
+ const opts = getOutputOptions();
31
+ return process.stdout.isTTY === true && !opts.json && !opts.verbose;
32
+ }
33
+ /**
34
+ * Create a braille spinner with SIGINT handling
35
+ */
36
+ function createSpinner(text) {
37
+ if (!shouldShowSpinner()) {
38
+ return null;
39
+ }
40
+ const spinner = ora({
41
+ text,
42
+ spinner: {
43
+ frames: BRAILLE_FRAMES,
44
+ interval: 80,
45
+ },
46
+ });
47
+ // Handle SIGINT to stop spinner gracefully
48
+ const sigintHandler = () => {
49
+ spinner.stop();
50
+ process.exit(130);
51
+ };
52
+ process.once('SIGINT', sigintHandler);
53
+ // Store handler for cleanup
54
+ spinner._sigintHandler = sigintHandler;
55
+ return spinner;
56
+ }
57
+ /**
58
+ * Stop spinner and clean up SIGINT handler
59
+ */
60
+ function stopSpinner(spinner) {
61
+ if (spinner) {
62
+ const handler = spinner._sigintHandler;
63
+ if (handler) {
64
+ process.removeListener('SIGINT', handler);
65
+ }
66
+ spinner.stop();
67
+ }
68
+ }
69
+ /**
70
+ * Get the effective catalog source from config or default
71
+ * Priority: 1) config.catalog.defaultSource, 2) DEFAULT_CATALOG_SOURCE
72
+ */
73
+ async function getEffectiveSource(getConfigPath) {
74
+ try {
75
+ const manager = new ConfigManager(getConfigPath());
76
+ const config = await manager.loadOrDefault();
77
+ return config.catalog?.defaultSource || DEFAULT_CATALOG_SOURCE;
78
+ }
79
+ catch {
80
+ return DEFAULT_CATALOG_SOURCE;
81
+ }
82
+ }
83
+ /**
84
+ * Create a RegistryClient for the effective source
85
+ * Validates source and checks authentication
86
+ */
87
+ async function createClientForSource(getConfigPath, sourceOverride) {
88
+ const sourceName = sourceOverride || (await getEffectiveSource(getConfigPath));
89
+ const source = getSource(sourceName);
90
+ if (!source) {
91
+ throw new Error(`Unknown catalog source: ${sourceName}`);
92
+ }
93
+ if (!isSourceReady(source)) {
94
+ throw new Error(getAuthErrorMessage(source));
95
+ }
96
+ return new RegistryClient({ baseUrl: source.baseUrl });
97
+ }
98
+ /**
99
+ * Cross-source search: search all available sources in parallel and merge results
100
+ */
101
+ async function searchAllSources(query, spinner) {
102
+ const allServers = [];
103
+ const skipped = [];
104
+ const warnings = [];
105
+ const seenNames = new Set();
106
+ // Separate ready and not-ready sources
107
+ const readySources = CATALOG_SOURCES.filter((source) => {
108
+ if (!isSourceReady(source)) {
109
+ skipped.push(source.name);
110
+ warnings.push(`(${source.name} skipped: ${source.authEnvVar} not set)`);
111
+ return false;
112
+ }
113
+ return true;
114
+ });
115
+ // Update spinner text for parallel search
116
+ if (spinner) {
117
+ spinner.text = `Searching ${readySources.length} source(s)...`;
118
+ }
119
+ // Search all ready sources in parallel
120
+ const searchPromises = readySources.map(async (source) => {
121
+ try {
122
+ const client = new RegistryClient({ baseUrl: source.baseUrl });
123
+ const servers = await client.searchServers(query);
124
+ return { source: source.name, servers, error: null };
125
+ }
126
+ catch (error) {
127
+ const msg = error instanceof Error ? error.message : 'Unknown error';
128
+ return { source: source.name, servers: [], error: msg };
129
+ }
130
+ });
131
+ const results = await Promise.all(searchPromises);
132
+ // Merge results and collect warnings
133
+ for (const result of results) {
134
+ if (result.error) {
135
+ warnings.push(`(${result.source} error: ${result.error})`);
136
+ continue;
137
+ }
138
+ // Add source info and deduplicate by name
139
+ for (const server of result.servers) {
140
+ const key = server.name || server.repository || JSON.stringify(server);
141
+ if (!seenNames.has(key)) {
142
+ seenNames.add(key);
143
+ allServers.push({ ...server, _source: result.source });
144
+ }
145
+ }
146
+ }
147
+ return { servers: allServers, skipped, warnings };
148
+ }
149
+ /**
150
+ * Format search results with two-line format
151
+ * Line 1: NAME (full)
152
+ * Line 2: VERSION + truncated DESC
153
+ * Optional: source info for cross-source search
154
+ */
155
+ function formatSearchResults(servers, showSource = false) {
156
+ console.log();
157
+ for (const server of servers) {
158
+ const name = server.name || '(unknown)';
159
+ const version = server.version || '-';
160
+ const desc = server.description || '';
161
+ // Line 1: Full name
162
+ console.log(` ${name}`);
163
+ // Line 2: version + description (truncated to fit)
164
+ const versionPart = ` v${version}`;
165
+ const sourceInfo = showSource && server._source ? ` [${server._source}]` : '';
166
+ const maxDescLen = TERM_WIDTH - versionPart.length - sourceInfo.length - 4;
167
+ const truncatedDesc = desc.length > maxDescLen ? desc.slice(0, maxDescLen - 1) + '…' : desc;
168
+ console.log(`${versionPart} ${truncatedDesc}${sourceInfo}`);
169
+ console.log(); // blank line between entries
170
+ }
171
+ }
172
+ /**
173
+ * Find similar servers for did-you-mean suggestions
174
+ * Uses already-fetched server list to avoid extra network calls
175
+ */
176
+ function findSimilarServers(query, servers, maxResults = 5) {
177
+ const lowerQuery = query.toLowerCase();
178
+ // Score servers by similarity
179
+ const scored = servers.map((server) => {
180
+ const name = server.name?.toLowerCase() || '';
181
+ const desc = server.description?.toLowerCase() || '';
182
+ let score = 0;
183
+ // Exact substring match in name (highest)
184
+ if (name.includes(lowerQuery)) {
185
+ score += 100;
186
+ }
187
+ // Substring match in description
188
+ if (desc.includes(lowerQuery)) {
189
+ score += 50;
190
+ }
191
+ // Prefix match on short name (e.g., query "ex" matches "ai.exa/exa")
192
+ const shortName = name.split('/').pop() || name;
193
+ if (shortName.startsWith(lowerQuery)) {
194
+ score += 80;
195
+ }
196
+ // Contains any query word
197
+ const queryWords = lowerQuery.split(/\s+/);
198
+ for (const word of queryWords) {
199
+ if (word.length >= 2 && (name.includes(word) || desc.includes(word))) {
200
+ score += 20;
201
+ }
202
+ }
203
+ return { server, score };
204
+ });
205
+ // Return top matches with score > 0
206
+ return scored
207
+ .filter((s) => s.score > 0)
208
+ .sort((a, b) => b.score - a.score)
209
+ .slice(0, maxResults)
210
+ .map((s) => s.server);
211
+ }
212
+ /**
213
+ * Format candidate servers for selection prompt
214
+ */
215
+ function formatCandidates(servers) {
216
+ const lines = [];
217
+ for (let i = 0; i < servers.length; i++) {
218
+ const s = servers[i];
219
+ const shortDesc = s.description
220
+ ? s.description.slice(0, 50) + (s.description.length > 50 ? '…' : '')
221
+ : '';
222
+ lines.push(` ${i + 1}. ${s.name}${shortDesc ? ` - ${shortDesc}` : ''}`);
223
+ }
224
+ return lines.join('\n');
225
+ }
226
+ /**
227
+ * Format server info for detailed view
228
+ */
229
+ function formatServerDetails(server) {
230
+ const lines = [];
231
+ lines.push(`Name: ${server.name || '(unknown)'}`);
232
+ lines.push(`Description: ${server.description || '(none)'}`);
233
+ lines.push(`Version: ${server.version || '(unknown)'}`);
234
+ if (server.versions && server.versions.length > 0) {
235
+ lines.push(`Versions: ${server.versions.join(', ')}`);
236
+ }
237
+ if (server.repository) {
238
+ lines.push(`Repository: ${server.repository}`);
239
+ }
240
+ if (server.homepage) {
241
+ lines.push(`Homepage: ${server.homepage}`);
242
+ }
243
+ if (server.transport) {
244
+ lines.push(`Transport: ${JSON.stringify(server.transport)}`);
245
+ }
246
+ return lines.join('\n');
247
+ }
248
+ /**
249
+ * Show not-found guidance with source info
250
+ */
251
+ function showNotFoundGuidance(query, currentSource, useAll, sourceOverride) {
252
+ const effectiveSource = sourceOverride || currentSource;
253
+ console.error(`Server not found: ${query} (source: ${effectiveSource})`);
254
+ console.error();
255
+ console.error('Try one of the following:');
256
+ // Show --all first if not already using it
257
+ if (!useAll) {
258
+ console.error(` pfscan cat search ${query} --all`);
259
+ }
260
+ // Show alternative sources
261
+ for (const source of CATALOG_SOURCES) {
262
+ if (source.name !== effectiveSource) {
263
+ console.error(` pfscan cat search ${query} --source ${source.name}`);
264
+ }
265
+ }
266
+ // Show source switch command
267
+ if (!sourceOverride && currentSource !== 'smithery') {
268
+ console.error(` pfscan cat sources set smithery`);
269
+ }
270
+ }
271
+ /**
272
+ * Handle registry errors with user-friendly messages
273
+ */
274
+ function handleRegistryError(error) {
275
+ if (error instanceof RegistryError) {
276
+ switch (error.code) {
277
+ case 'NETWORK':
278
+ console.error(`Network error: ${error.message}`);
279
+ console.error('Check your internet connection or try again later.');
280
+ break;
281
+ case 'NOT_FOUND':
282
+ console.error(`Server not found.`);
283
+ console.error('Use "pfscan catalog search <query>" to find available servers.');
284
+ break;
285
+ case 'TIMEOUT':
286
+ console.error('Request timed out.');
287
+ console.error('The registry may be slow or unavailable. Try again later.');
288
+ break;
289
+ case 'PARSE':
290
+ console.error('Failed to parse registry response.');
291
+ console.error('The registry API may have changed.');
292
+ break;
293
+ default:
294
+ console.error(`Registry error: ${error.message}`);
295
+ }
296
+ }
297
+ else if (error instanceof Error) {
298
+ console.error(`Error: ${error.message}`);
299
+ }
300
+ else {
301
+ console.error('An unknown error occurred.');
302
+ }
303
+ process.exit(1);
304
+ }
305
+ /**
306
+ * Show sources list (shared by 'sources' and 'sources list')
307
+ */
308
+ async function showSourcesList(getConfigPath) {
309
+ const opts = getOutputOptions();
310
+ const defaultSource = await getEffectiveSource(getConfigPath);
311
+ if (opts.json) {
312
+ output({
313
+ defaultSource,
314
+ sources: CATALOG_SOURCES.map((s) => ({
315
+ name: s.name,
316
+ baseUrl: s.baseUrl,
317
+ authRequired: s.authRequired,
318
+ authEnvVar: s.authEnvVar,
319
+ ready: isSourceReady(s),
320
+ })),
321
+ });
322
+ return;
323
+ }
324
+ console.log(`Default catalog source: ${defaultSource}`);
325
+ console.log();
326
+ console.log('Sources:');
327
+ for (const source of CATALOG_SOURCES) {
328
+ const isDefault = source.name === defaultSource;
329
+ console.log(formatSourceLine(source, isDefault));
330
+ }
331
+ console.log();
332
+ console.log('Tip: pfscan cat sources set <name>');
333
+ }
334
+ export function createCatalogCommand(getConfigPath) {
335
+ const cmd = new Command('catalog').description('Search and view MCP servers from registry');
336
+ // catalog search <query>
337
+ cmd
338
+ .command('search')
339
+ .description('Search for MCP servers by name or description')
340
+ .argument('<query>', 'Search query')
341
+ .option('--source <name>', 'Use specific catalog source')
342
+ .option('--all', 'Search all available catalog sources')
343
+ .action(async (query, options) => {
344
+ const opts = getOutputOptions();
345
+ const currentSource = await getEffectiveSource(getConfigPath);
346
+ // Cross-source search with --all
347
+ if (options.all) {
348
+ const spinner = createSpinner(`Searching all sources for "${query}"...`);
349
+ try {
350
+ spinner?.start();
351
+ const { servers, warnings } = await searchAllSources(query, spinner);
352
+ stopSpinner(spinner);
353
+ if (opts.json) {
354
+ output(servers.map((s) => ({ ...s, source: s._source })));
355
+ return;
356
+ }
357
+ // Show warnings for skipped sources
358
+ for (const warning of warnings) {
359
+ console.log(warning);
360
+ }
361
+ if (servers.length === 0) {
362
+ console.log(`No servers found matching "${query}" across all sources.`);
363
+ return;
364
+ }
365
+ // Two-line format with source info
366
+ formatSearchResults(servers, true);
367
+ console.log(`${servers.length} server(s) found across sources.`);
368
+ console.log();
369
+ // Improved Tip: embed full ID if single result
370
+ if (servers.length === 1 && servers[0].name) {
371
+ console.log(`Tip: pfscan cat view "${servers[0].name}"`);
372
+ }
373
+ else {
374
+ console.log('Tip: pfscan cat view <name>');
375
+ }
376
+ }
377
+ catch (error) {
378
+ stopSpinner(spinner);
379
+ handleRegistryError(error);
380
+ }
381
+ return;
382
+ }
383
+ // Single source search
384
+ const spinner = createSpinner(`Searching for "${query}"...`);
385
+ try {
386
+ const client = await createClientForSource(getConfigPath, options.source);
387
+ spinner?.start();
388
+ const servers = await client.searchServers(query);
389
+ stopSpinner(spinner);
390
+ if (opts.json) {
391
+ output(servers);
392
+ return;
393
+ }
394
+ if (servers.length === 0) {
395
+ console.log(`No servers found matching "${query}" (source: ${options.source || currentSource}).`);
396
+ console.log();
397
+ console.log('Try searching all sources:');
398
+ console.log(` pfscan cat search ${query} --all`);
399
+ return;
400
+ }
401
+ // Two-line format with full NAME
402
+ formatSearchResults(servers);
403
+ console.log(`${servers.length} server(s) found.`);
404
+ console.log();
405
+ // Improved Tip: embed full ID if single result
406
+ if (servers.length === 1 && servers[0].name) {
407
+ console.log(`Tip: pfscan cat view "${servers[0].name}"`);
408
+ }
409
+ else {
410
+ console.log('Tip: pfscan cat view <name>');
411
+ }
412
+ }
413
+ catch (error) {
414
+ stopSpinner(spinner);
415
+ handleRegistryError(error);
416
+ }
417
+ });
418
+ // catalog view <server> [field]
419
+ cmd
420
+ .command('view')
421
+ .description('View server details or a specific field')
422
+ .argument('<server>', 'Server name')
423
+ .argument('[field]', 'Specific field to display')
424
+ .option('--source <name>', 'Use specific catalog source')
425
+ .action(async (serverName, field, options) => {
426
+ const opts = getOutputOptions();
427
+ const currentSource = await getEffectiveSource(getConfigPath);
428
+ const spinner = createSpinner(`Fetching "${serverName}"...`);
429
+ try {
430
+ const client = await createClientForSource(getConfigPath, options.source);
431
+ spinner?.start();
432
+ let server = await client.getServer(serverName);
433
+ // Fallback: if not found, search and try to resolve
434
+ if (!server) {
435
+ // Get all servers for similarity search
436
+ const allServers = await client.listServers();
437
+ const similar = findSimilarServers(serverName, allServers);
438
+ stopSpinner(spinner);
439
+ if (similar.length === 0) {
440
+ // No suggestions available - show enhanced guidance
441
+ if (opts.json) {
442
+ output({
443
+ error: 'Server not found',
444
+ query: serverName,
445
+ source: options.source || currentSource,
446
+ });
447
+ }
448
+ else {
449
+ showNotFoundGuidance(serverName, currentSource, false, options.source);
450
+ }
451
+ process.exit(1);
452
+ }
453
+ if (similar.length === 1) {
454
+ // Single match - auto-resolve
455
+ server = similar[0];
456
+ console.log(`Resolved "${serverName}" → ${server.name}`);
457
+ console.log();
458
+ }
459
+ else {
460
+ // Multiple candidates - show did-you-mean
461
+ console.error(`Server not found: ${serverName} (source: ${options.source || currentSource})`);
462
+ console.error();
463
+ console.error('Did you mean:');
464
+ console.error(formatCandidates(similar));
465
+ console.error();
466
+ console.error('Tip: pfscan cat view <full-name>');
467
+ process.exit(1);
468
+ }
469
+ }
470
+ else {
471
+ stopSpinner(spinner);
472
+ }
473
+ // If field specified, show only that field
474
+ if (field) {
475
+ if (!isSupportedField(field)) {
476
+ console.error(`Unknown field: ${field}`);
477
+ console.error(`Supported fields: ${SUPPORTED_FIELDS.join(', ')}`);
478
+ process.exit(1);
479
+ }
480
+ const value = getFieldValue(server, field);
481
+ if (opts.json) {
482
+ output({ [field]: value });
483
+ return;
484
+ }
485
+ console.log(formatFieldValue(value));
486
+ return;
487
+ }
488
+ // Show all details
489
+ if (opts.json) {
490
+ output(server);
491
+ return;
492
+ }
493
+ console.log();
494
+ console.log(formatServerDetails(server));
495
+ console.log();
496
+ }
497
+ catch (error) {
498
+ stopSpinner(spinner);
499
+ handleRegistryError(error);
500
+ }
501
+ });
502
+ // catalog sources - show available sources
503
+ const sourcesCmd = cmd
504
+ .command('sources')
505
+ .description('Manage catalog sources');
506
+ // Default action for 'sources' (no subcommand)
507
+ sourcesCmd.action(async () => {
508
+ await showSourcesList(getConfigPath);
509
+ });
510
+ // catalog sources list - explicit list subcommand
511
+ sourcesCmd
512
+ .command('list')
513
+ .description('List available catalog sources')
514
+ .action(async () => {
515
+ await showSourcesList(getConfigPath);
516
+ });
517
+ // catalog sources set <name> - set default source
518
+ sourcesCmd
519
+ .command('set')
520
+ .description('Set default catalog source')
521
+ .argument('<name>', 'Source name')
522
+ .action(async (name) => {
523
+ const opts = getOutputOptions();
524
+ // Validate source name
525
+ if (!isValidSource(name)) {
526
+ if (opts.json) {
527
+ output({ success: false, error: `Unknown catalog source: ${name}` });
528
+ }
529
+ else {
530
+ outputError(`Unknown catalog source: ${name}`);
531
+ console.error();
532
+ console.error('Available sources:');
533
+ for (const sourceName of getSourceNames()) {
534
+ console.error(` ${sourceName}`);
535
+ }
536
+ }
537
+ process.exit(1);
538
+ }
539
+ try {
540
+ const manager = new ConfigManager(getConfigPath());
541
+ const config = await manager.loadOrDefault();
542
+ // Update catalog config
543
+ config.catalog = config.catalog || {};
544
+ config.catalog.defaultSource = name;
545
+ await manager.save(config);
546
+ if (opts.json) {
547
+ output({ success: true, defaultSource: name });
548
+ }
549
+ else {
550
+ outputSuccess(`Default catalog source set to: ${name}`);
551
+ }
552
+ }
553
+ catch (error) {
554
+ if (opts.json) {
555
+ output({
556
+ success: false,
557
+ error: error instanceof Error ? error.message : 'Unknown error',
558
+ });
559
+ }
560
+ else {
561
+ outputError('Failed to save config', error instanceof Error ? error : undefined);
562
+ }
563
+ process.exit(1);
564
+ }
565
+ });
566
+ return cmd;
567
+ }
568
+ //# sourceMappingURL=catalog.js.map