@shnitzel/plugscout 0.3.27 → 0.3.28

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.
@@ -480,7 +480,7 @@ async function handleList(args) {
480
480
  if (details) {
481
481
  console.log(renderCatalogDecisionDetails(filtered, policy, insights));
482
482
  }
483
- await promptResultBrowser(filtered.map((e) => ({ id: e.item.id, name: e.item.name })));
483
+ await promptResultBrowser(filtered.map((e) => ({ id: e.item.id, name: e.item.name, url: buildItemLinks(e.item)[0]?.url })));
484
484
  }
485
485
  async function handleShow(args) {
486
486
  const id = readFlag(args, '--id');
@@ -560,7 +560,7 @@ async function handleSearch(args) {
560
560
  name: entry.item.name
561
561
  }))));
562
562
  printHint('Use `show --id <catalog-id>` for full detail.');
563
- await promptResultBrowser(matches.map((e) => ({ id: e.item.id, name: e.item.name })));
563
+ await promptResultBrowser(matches.map((e) => ({ id: e.item.id, name: e.item.name, url: buildItemLinks(e.item)[0]?.url })));
564
564
  }
565
565
  async function handleExplain(args) {
566
566
  const kinds = readKinds(args);
@@ -681,12 +681,16 @@ async function handleTop(args) {
681
681
  printHint('Review each suggestion before installing. Do not install blindly from rank alone.');
682
682
  printHint(`Risk scale (lower is safer): ${formatRiskScale(policy)}`);
683
683
  printHint('Use `show --id <catalog-id>` or `assess --id <catalog-id>` for deep inspection.');
684
+ const topCatalogItems = await loadCatalogItems();
685
+ const topCatalogMap = new Map(topCatalogItems.map((item) => [item.id, item]));
684
686
  if (details) {
685
- const [catalogItems, insights] = await Promise.all([loadCatalogItems(), loadItemInsights()]);
686
- const catalogMap = new Map(catalogItems.map((item) => [item.id, item]));
687
- console.log(renderRecommendationDecisionDetails(safe, catalogMap, policy, insights));
687
+ const insights = await loadItemInsights();
688
+ console.log(renderRecommendationDecisionDetails(safe, topCatalogMap, policy, insights));
688
689
  }
689
- await promptResultBrowser(safe.map((e) => ({ id: e.id, name: '' })));
690
+ await promptResultBrowser(safe.map((e) => {
691
+ const item = topCatalogMap.get(e.id);
692
+ return { id: e.id, name: '', url: item ? buildItemLinks(item)[0]?.url : undefined };
693
+ }));
690
694
  }
691
695
  async function handleSync(args) {
692
696
  const kinds = readKinds(args);
@@ -787,7 +791,12 @@ async function handleRecommend(args) {
787
791
  }
788
792
  printHint('Next: run `show --id <catalog-id>` or `install --id <catalog-id> --yes`.');
789
793
  if (format !== 'json') {
790
- await promptResultBrowser(ranked.map((e) => ({ id: e.id, name: '' })));
794
+ const recCatalogItems = await loadCatalogItems();
795
+ const recCatalogMap = new Map(recCatalogItems.map((item) => [item.id, item]));
796
+ await promptResultBrowser(ranked.map((e) => {
797
+ const item = recCatalogMap.get(e.id);
798
+ return { id: e.id, name: '', url: item ? buildItemLinks(item)[0]?.url : undefined };
799
+ }));
791
800
  }
792
801
  }
793
802
  async function handleWeb(args) {
@@ -1173,15 +1182,16 @@ async function promptResultBrowser(entries) {
1173
1182
  const ENTER = '\r';
1174
1183
  const CTRL_C = '';
1175
1184
  const Q = 'q';
1176
- // Single-line navigator no second table. The rendered results above are the reference.
1185
+ // Two-line navigator: id/name line + url line (blank if none). Always writes 2 lines so cursor math is stable.
1177
1186
  function renderNavigator(firstRender) {
1178
1187
  if (!firstRender) {
1179
- moveCursor(process.stdout, 0, -1);
1188
+ moveCursor(process.stdout, 0, -2);
1180
1189
  clearScreenDown(process.stdout);
1181
1190
  }
1182
1191
  const entry = entries[selected];
1183
1192
  const label = entry.name ? `${entry.id} \x1b[90m${entry.name}\x1b[0m` : entry.id;
1184
1193
  process.stdout.write(` \x1b[36m❯\x1b[0m ${label} \x1b[90m(${selected + 1}/${entries.length})\x1b[0m\n`);
1194
+ process.stdout.write(entry.url ? ` \x1b[90m${entry.url}\x1b[0m\n` : '\n');
1185
1195
  }
1186
1196
  // eslint-disable-next-line prefer-const
1187
1197
  let running = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shnitzel/plugscout",
3
- "version": "0.3.27",
3
+ "version": "0.3.28",
4
4
  "description": "Claude plugins + Claude connectors + Copilot extensions + Skills + MCP security intelligence framework",
5
5
  "private": false,
6
6
  "type": "module",