@sun-asterisk/sunlint 1.3.38 → 1.3.39

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 CHANGED
@@ -24,8 +24,9 @@ program
24
24
  .command('init [directory]')
25
25
  .description('Initialize a project with SunLint code quality skill and AGENTS.md')
26
26
  .option('-f, --force', 'Overwrite existing files')
27
- .option('-t, --tool <tool>', `Target AI tool (default: ${DEFAULT_TOOL})`, DEFAULT_TOOL)
28
- .option('-l, --language <language>', `Target language (default: typescript)`, 'typescript')
27
+ .option('-t, --tool <tool>', `Target AI tool (default: ${DEFAULT_TOOL})`)
28
+ .option('-l, --language <language>', `Target language (default: typescript)`)
29
+ .option('--non-interactive', 'Disable interactive prompts')
29
30
  .addHelpText('after', `
30
31
  AI Tool Options:
31
32
  ${getAvailableToolsHelp()}
@@ -7,6 +7,7 @@
7
7
  const fs = require('fs');
8
8
  const path = require('path');
9
9
  const chalk = require('chalk');
10
+ const readline = require('readline');
10
11
 
11
12
  // Path to the bundled skill directory (relative to this file in the package)
12
13
  const SKILL_SOURCE_DIR = path.join(__dirname, '..', 'skill-assets', 'sunlint-code-quality');
@@ -51,6 +52,52 @@ function getAvailableToolsHelp() {
51
52
  .join('\n');
52
53
  }
53
54
 
55
+ /**
56
+ * Get available languages from rules directory
57
+ */
58
+ function getAvailableLanguages() {
59
+ const rulesDir = path.join(SKILL_SOURCE_DIR, 'rules');
60
+ if (!fs.existsSync(rulesDir)) return ['typescript', 'csharp', 'python'];
61
+
62
+ return fs.readdirSync(rulesDir)
63
+ .filter(item => {
64
+ const fullPath = path.join(rulesDir, item);
65
+ return fs.statSync(fullPath).isDirectory();
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Interactive selection helper
71
+ */
72
+ async function promptSelection(question, options) {
73
+ const rl = readline.createInterface({
74
+ input: process.stdin,
75
+ output: process.stdout
76
+ });
77
+
78
+ return new Promise((resolve) => {
79
+ console.log(chalk.cyan(`\n? ${question}`));
80
+ options.forEach((opt, i) => {
81
+ console.log(` ${chalk.white(i + 1)}) ${opt.name || opt}`);
82
+ });
83
+
84
+ const ask = () => {
85
+ rl.question(chalk.yellow(`\nSelect [1-${options.length}]: `), (answer) => {
86
+ const choice = parseInt(answer.trim());
87
+ if (choice >= 1 && choice <= options.length) {
88
+ rl.close();
89
+ const selected = options[choice - 1];
90
+ resolve(selected.key || selected);
91
+ } else {
92
+ console.log(chalk.red(`Invalid selection. Please enter a number between 1 and ${options.length}.`));
93
+ ask();
94
+ }
95
+ });
96
+ };
97
+ ask();
98
+ });
99
+ }
100
+
54
101
  /**
55
102
  * Initialize a project with SunLint skill and AGENTS.md
56
103
  * @param {string} targetDir - The target project directory
@@ -58,7 +105,33 @@ function getAvailableToolsHelp() {
58
105
  */
59
106
  async function initProject(targetDir, options = {}) {
60
107
  const resolvedTargetDir = path.resolve(targetDir);
61
- const tool = options.tool || DEFAULT_TOOL;
108
+
109
+ let tool = options.tool;
110
+ let language = options.language;
111
+
112
+ // Interactive step-by-step setup if options are missing and in TTY
113
+ if (process.stdin.isTTY && process.stdout.isTTY && !options.nonInteractive) {
114
+ if (!tool) {
115
+ const toolOptions = Object.entries(AI_TOOL_CONFIG).map(([key, config]) => ({
116
+ key,
117
+ name: config.name
118
+ }));
119
+ tool = await promptSelection('Select Target AI Tool', toolOptions);
120
+ }
121
+
122
+ if (!language) {
123
+ const languageOptions = getAvailableLanguages();
124
+ language = await promptSelection('Select Target Language', languageOptions);
125
+ }
126
+ }
127
+
128
+ // Apply defaults if still missing (non-interactive or failed prompt)
129
+ tool = tool || DEFAULT_TOOL;
130
+ language = language || 'typescript';
131
+
132
+ // Update options for subsequent steps
133
+ options.tool = tool;
134
+ options.language = language;
62
135
 
63
136
  // Validate tool option
64
137
  if (!AI_TOOL_CONFIG[tool]) {
@@ -72,6 +145,7 @@ async function initProject(targetDir, options = {}) {
72
145
 
73
146
  console.log(chalk.cyan('\n☀️ SunLint Init - Setting up code quality standards...\n'));
74
147
  console.log(chalk.blue(` 🤖 Target AI Tool: ${toolConfig.name}`));
148
+ console.log(chalk.blue(` 📝 Target Language: ${language}`));
75
149
 
76
150
  // Validate target directory exists
77
151
  if (!fs.existsSync(resolvedTargetDir)) {
@@ -91,7 +165,7 @@ async function initProject(targetDir, options = {}) {
91
165
  console.log(chalk.white(' Files created/updated:'));
92
166
  console.log(chalk.gray(` • ${path.relative(resolvedTargetDir, skillTargetDir)}/`));
93
167
  console.log(chalk.gray(` • AGENTS.md`));
94
- console.log(chalk.cyan(`\n📖 ${toolConfig.name} will now follow SunLint code quality standards.\n`));
168
+ console.log(chalk.cyan(`\n📖 ${toolConfig.name} will now follow SunLint code quality standards for ${language}.\n`));
95
169
  }
96
170
 
97
171
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sun-asterisk/sunlint",
3
- "version": "1.3.38",
3
+ "version": "1.3.39",
4
4
  "description": "☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards",
5
5
  "main": "cli.js",
6
6
  "bin": {