korext 0.9.10 → 0.9.11

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 (2) hide show
  1. package/bin/korext.js +62 -12
  2. package/package.json +1 -1
package/bin/korext.js CHANGED
@@ -630,18 +630,65 @@ program
630
630
  });
631
631
 
632
632
  console.log();
633
- const industryInput = await ask(chalk.bold(' Select industries (comma-separated numbers or IDs): '));
633
+ const industryInput = await ask(chalk.bold(' Select industries or packs (numbers, IDs, or names): '));
634
634
 
635
- // Parse user input (numbers or IDs)
636
- const selectedIndustries = industryInput.split(',').map(s => s.trim()).filter(Boolean).map(s => {
637
- const num = parseInt(s, 10);
635
+ // Parse user input: accept numbers, industry IDs, industry names (fuzzy), or pack IDs
636
+ const rawTokens = industryInput.split(',').map(s => s.trim()).filter(Boolean);
637
+ const selectedIndustries = [];
638
+ const directPacks = [];
639
+
640
+ for (const token of rawTokens) {
641
+ const lower = token.toLowerCase();
642
+
643
+ // Strategy 1: Number (e.g., "8" for Finance)
644
+ const num = parseInt(token, 10);
638
645
  if (!isNaN(num) && num >= 1 && num <= sortedIndustries.length) {
639
- return sortedIndustries[num - 1][0];
646
+ selectedIndustries.push(sortedIndustries[num - 1][0]);
647
+ continue;
648
+ }
649
+
650
+ // Strategy 2: Industry ID exact match (e.g., "finance")
651
+ if (taxonomy.industries[lower]) {
652
+ selectedIndustries.push(lower);
653
+ continue;
654
+ }
655
+
656
+ // Strategy 3: Industry label fuzzy match (e.g., "Finance", "health", "aero")
657
+ const labelMatch = sortedIndustries.find(([id, group]) =>
658
+ group.label.toLowerCase().startsWith(lower)
659
+ );
660
+ if (labelMatch) {
661
+ selectedIndustries.push(labelMatch[0]);
662
+ console.log(chalk.dim(` "${token}" matched industry: ${labelMatch[1].label}`));
663
+ continue;
664
+ }
665
+
666
+ // Strategy 4: Direct pack ID (e.g., "web", "pci-dss-v1", "security")
667
+ const allPackIds = Object.keys(defs.packs);
668
+ if (allPackIds.includes(lower)) {
669
+ directPacks.push(lower);
670
+ console.log(chalk.dim(` "${token}" is a pack ID, adding directly.`));
671
+ continue;
640
672
  }
641
- return s.toLowerCase();
642
- }).filter(id => taxonomy.industries[id]);
643
673
 
644
- if (selectedIndustries.length === 0) {
674
+ // Nothing matched
675
+ console.log(chalk.yellow(` Unknown input: "${token}" (not an industry, pack ID, or name)`));
676
+ }
677
+
678
+ // If user typed only pack IDs (e.g., "web" or "web, security"), skip region prompt
679
+ if (selectedIndustries.length === 0 && directPacks.length > 0) {
680
+ const config = {
681
+ targetPacks: directPacks,
682
+ exclude: ['node_modules', 'dist', 'build', '.next']
683
+ };
684
+ fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));
685
+ console.log(chalk.green(`\n Created ${outputPath} with packs: ${directPacks.join(', ')}\n`));
686
+ console.log(chalk.dim(` Run: ${chalk.green('korext enforce .')} to enforce these packs.\n`));
687
+ rl.close();
688
+ process.exit(0);
689
+ }
690
+
691
+ if (selectedIndustries.length === 0 && directPacks.length === 0) {
645
692
  console.log(chalk.yellow('\n No valid industries selected. Using default: web\n'));
646
693
  const config = {
647
694
  targetPacks: ['web'],
@@ -676,22 +723,25 @@ program
676
723
  }
677
724
  }
678
725
 
679
- // Resolve packs
726
+ // Resolve packs from industries
680
727
  const resolvedPacks = resolvePacksForIndustryRegion(
681
728
  selectedIndustries.join(','),
682
729
  selectedRegion,
683
730
  taxonomy
684
731
  );
685
732
 
686
- console.log(chalk.green(`\n Resolved ${resolvedPacks.length} packs for ${selectedIndustries.map(id => INDUSTRY_LABELS[id]).join(', ')}${selectedRegion ? ` (${REGION_LABELS[selectedRegion] || selectedRegion})` : ''}:`));
687
- for (const pid of resolvedPacks) {
733
+ // Merge any direct pack IDs the user typed alongside industries
734
+ const allPacks = [...new Set([...resolvedPacks, ...directPacks])];
735
+
736
+ console.log(chalk.green(`\n Resolved ${allPacks.length} packs for ${selectedIndustries.map(id => INDUSTRY_LABELS[id]).join(', ')}${selectedRegion ? ` (${REGION_LABELS[selectedRegion] || selectedRegion})` : ''}${directPacks.length > 0 ? ` + ${directPacks.join(', ')}` : ''}:`));
737
+ for (const pid of allPacks) {
688
738
  console.log(` ${chalk.cyan(pid)}`);
689
739
  }
690
740
 
691
741
  const config = {
692
742
  industry: selectedIndustries.join(','),
693
743
  ...(selectedRegion && { region: selectedRegion }),
694
- targetPacks: resolvedPacks,
744
+ targetPacks: allPacks,
695
745
  exclude: ['node_modules', 'dist', 'build', '.next']
696
746
  };
697
747
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "korext",
3
- "version": "0.9.10",
3
+ "version": "0.9.11",
4
4
  "mcpName": "io.github.Korext/governance",
5
5
  "description": "Korext Command Line Interface",
6
6
  "type": "module",