Initial commit
This commit is contained in:
423
skills/inquirer-patterns/scripts/generate-prompt.sh
Executable file
423
skills/inquirer-patterns/scripts/generate-prompt.sh
Executable file
@@ -0,0 +1,423 @@
|
||||
#!/bin/bash
|
||||
|
||||
# generate-prompt.sh
|
||||
# Generate boilerplate prompt code for Node.js or Python
|
||||
|
||||
set -e
|
||||
|
||||
# Default values
|
||||
PROMPT_TYPE=""
|
||||
LANGUAGE=""
|
||||
OUTPUT_FILE=""
|
||||
|
||||
# Color codes
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Usage information
|
||||
usage() {
|
||||
echo "Usage: $0 --type <prompt-type> --lang <language> [--output <file>]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " --type Prompt type: text, list, checkbox, password, autocomplete, conditional"
|
||||
echo " --lang Language: js (Node.js) or py (Python)"
|
||||
echo " --output Output file path (optional)"
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " $0 --type text --lang js --output my-prompt.js"
|
||||
echo " $0 --type checkbox --lang py"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--type)
|
||||
PROMPT_TYPE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--lang)
|
||||
LANGUAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--output)
|
||||
OUTPUT_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate arguments
|
||||
if [ -z "$PROMPT_TYPE" ] || [ -z "$LANGUAGE" ]; then
|
||||
echo "Error: --type and --lang are required"
|
||||
usage
|
||||
fi
|
||||
|
||||
# Validate prompt type
|
||||
VALID_TYPES=("text" "list" "checkbox" "password" "autocomplete" "conditional")
|
||||
if [[ ! " ${VALID_TYPES[@]} " =~ " ${PROMPT_TYPE} " ]]; then
|
||||
echo "Error: Invalid prompt type '$PROMPT_TYPE'"
|
||||
echo "Valid types: ${VALID_TYPES[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate language
|
||||
if [ "$LANGUAGE" != "js" ] && [ "$LANGUAGE" != "py" ]; then
|
||||
echo "Error: Language must be 'js' or 'py'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set default output file if not specified
|
||||
if [ -z "$OUTPUT_FILE" ]; then
|
||||
if [ "$LANGUAGE" == "js" ]; then
|
||||
OUTPUT_FILE="${PROMPT_TYPE}-prompt.js"
|
||||
else
|
||||
OUTPUT_FILE="${PROMPT_TYPE}_prompt.py"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}🔧 Generating $PROMPT_TYPE prompt for $LANGUAGE...${NC}"
|
||||
echo
|
||||
|
||||
# Generate Node.js code
|
||||
if [ "$LANGUAGE" == "js" ]; then
|
||||
case $PROMPT_TYPE in
|
||||
text)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import inquirer from 'inquirer';
|
||||
|
||||
async function textPrompt() {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'fieldName',
|
||||
message: 'Enter value:',
|
||||
validate: (input) => input.length > 0 || 'This field is required'
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('Answer:', answers.fieldName);
|
||||
return answers;
|
||||
}
|
||||
|
||||
// Run if executed directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
textPrompt().then(() => process.exit(0)).catch(console.error);
|
||||
}
|
||||
|
||||
export { textPrompt };
|
||||
EOF
|
||||
;;
|
||||
list)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import inquirer from 'inquirer';
|
||||
|
||||
async function listPrompt() {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'selection',
|
||||
message: 'Choose an option:',
|
||||
choices: ['Option 1', 'Option 2', 'Option 3']
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('Selected:', answers.selection);
|
||||
return answers;
|
||||
}
|
||||
|
||||
// Run if executed directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
listPrompt().then(() => process.exit(0)).catch(console.error);
|
||||
}
|
||||
|
||||
export { listPrompt };
|
||||
EOF
|
||||
;;
|
||||
checkbox)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import inquirer from 'inquirer';
|
||||
|
||||
async function checkboxPrompt() {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'selections',
|
||||
message: 'Select options:',
|
||||
choices: ['Option 1', 'Option 2', 'Option 3'],
|
||||
validate: (choices) => choices.length > 0 || 'Select at least one option'
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('Selected:', answers.selections);
|
||||
return answers;
|
||||
}
|
||||
|
||||
// Run if executed directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
checkboxPrompt().then(() => process.exit(0)).catch(console.error);
|
||||
}
|
||||
|
||||
export { checkboxPrompt };
|
||||
EOF
|
||||
;;
|
||||
password)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import inquirer from 'inquirer';
|
||||
|
||||
async function passwordPrompt() {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'password',
|
||||
name: 'password',
|
||||
message: 'Enter password:',
|
||||
mask: '*',
|
||||
validate: (input) => input.length >= 8 || 'Password must be at least 8 characters'
|
||||
},
|
||||
{
|
||||
type: 'password',
|
||||
name: 'confirm',
|
||||
message: 'Confirm password:',
|
||||
mask: '*',
|
||||
validate: (input, answers) => input === answers.password || 'Passwords do not match'
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('Password set successfully');
|
||||
return answers;
|
||||
}
|
||||
|
||||
// Run if executed directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
passwordPrompt().then(() => process.exit(0)).catch(console.error);
|
||||
}
|
||||
|
||||
export { passwordPrompt };
|
||||
EOF
|
||||
;;
|
||||
autocomplete)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import inquirer from 'inquirer';
|
||||
import inquirerAutocomplete from 'inquirer-autocomplete-prompt';
|
||||
|
||||
inquirer.registerPrompt('autocomplete', inquirerAutocomplete);
|
||||
|
||||
const choices = ['Option 1', 'Option 2', 'Option 3', 'Option 4', 'Option 5'];
|
||||
|
||||
function searchChoices(input) {
|
||||
if (!input) return choices;
|
||||
return choices.filter(choice => choice.toLowerCase().includes(input.toLowerCase()));
|
||||
}
|
||||
|
||||
async function autocompletePrompt() {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'autocomplete',
|
||||
name: 'selection',
|
||||
message: 'Search for an option:',
|
||||
source: (answersSoFar, input) => Promise.resolve(searchChoices(input))
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('Selected:', answers.selection);
|
||||
return answers;
|
||||
}
|
||||
|
||||
// Run if executed directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
autocompletePrompt().then(() => process.exit(0)).catch(console.error);
|
||||
}
|
||||
|
||||
export { autocompletePrompt };
|
||||
EOF
|
||||
;;
|
||||
conditional)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import inquirer from 'inquirer';
|
||||
|
||||
async function conditionalPrompt() {
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'continue',
|
||||
message: 'Do you want to continue?',
|
||||
default: true
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'details',
|
||||
message: 'Enter details:',
|
||||
when: (answers) => answers.continue,
|
||||
validate: (input) => input.length > 0 || 'Details required'
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('Answers:', answers);
|
||||
return answers;
|
||||
}
|
||||
|
||||
// Run if executed directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
conditionalPrompt().then(() => process.exit(0)).catch(console.error);
|
||||
}
|
||||
|
||||
export { conditionalPrompt };
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Generate Python code
|
||||
if [ "$LANGUAGE" == "py" ]; then
|
||||
case $PROMPT_TYPE in
|
||||
text)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import questionary
|
||||
|
||||
def text_prompt():
|
||||
answer = questionary.text(
|
||||
"Enter value:",
|
||||
validate=lambda text: len(text) > 0 or "This field is required"
|
||||
).ask()
|
||||
|
||||
print(f"Answer: {answer}")
|
||||
return answer
|
||||
|
||||
if __name__ == "__main__":
|
||||
text_prompt()
|
||||
EOF
|
||||
;;
|
||||
list)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import questionary
|
||||
|
||||
def list_prompt():
|
||||
answer = questionary.select(
|
||||
"Choose an option:",
|
||||
choices=['Option 1', 'Option 2', 'Option 3']
|
||||
).ask()
|
||||
|
||||
print(f"Selected: {answer}")
|
||||
return answer
|
||||
|
||||
if __name__ == "__main__":
|
||||
list_prompt()
|
||||
EOF
|
||||
;;
|
||||
checkbox)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import questionary
|
||||
|
||||
def checkbox_prompt():
|
||||
answers = questionary.checkbox(
|
||||
"Select options:",
|
||||
choices=['Option 1', 'Option 2', 'Option 3'],
|
||||
validate=lambda choices: len(choices) > 0 or "Select at least one option"
|
||||
).ask()
|
||||
|
||||
print(f"Selected: {answers}")
|
||||
return answers
|
||||
|
||||
if __name__ == "__main__":
|
||||
checkbox_prompt()
|
||||
EOF
|
||||
;;
|
||||
password)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import questionary
|
||||
|
||||
def password_prompt():
|
||||
password = questionary.password(
|
||||
"Enter password:",
|
||||
validate=lambda text: len(text) >= 8 or "Password must be at least 8 characters"
|
||||
).ask()
|
||||
|
||||
confirm = questionary.password(
|
||||
"Confirm password:",
|
||||
validate=lambda text: text == password or "Passwords do not match"
|
||||
).ask()
|
||||
|
||||
print("Password set successfully")
|
||||
return password
|
||||
|
||||
if __name__ == "__main__":
|
||||
password_prompt()
|
||||
EOF
|
||||
;;
|
||||
autocomplete)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import questionary
|
||||
|
||||
def autocomplete_prompt():
|
||||
choices = ['Option 1', 'Option 2', 'Option 3', 'Option 4', 'Option 5']
|
||||
|
||||
answer = questionary.autocomplete(
|
||||
"Search for an option:",
|
||||
choices=choices
|
||||
).ask()
|
||||
|
||||
print(f"Selected: {answer}")
|
||||
return answer
|
||||
|
||||
if __name__ == "__main__":
|
||||
autocomplete_prompt()
|
||||
EOF
|
||||
;;
|
||||
conditional)
|
||||
cat > "$OUTPUT_FILE" << 'EOF'
|
||||
import questionary
|
||||
|
||||
def conditional_prompt():
|
||||
continue_prompt = questionary.confirm(
|
||||
"Do you want to continue?",
|
||||
default=True
|
||||
).ask()
|
||||
|
||||
details = None
|
||||
if continue_prompt:
|
||||
details = questionary.text(
|
||||
"Enter details:",
|
||||
validate=lambda text: len(text) > 0 or "Details required"
|
||||
).ask()
|
||||
|
||||
result = {
|
||||
'continue': continue_prompt,
|
||||
'details': details
|
||||
}
|
||||
|
||||
print(f"Answers: {result}")
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
conditional_prompt()
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Make Python files executable
|
||||
if [ "$LANGUAGE" == "py" ]; then
|
||||
chmod +x "$OUTPUT_FILE"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ Generated: $OUTPUT_FILE${NC}"
|
||||
echo
|
||||
echo -e "${YELLOW}📝 Next steps:${NC}"
|
||||
echo " 1. Edit the generated file to customize your prompt"
|
||||
if [ "$LANGUAGE" == "js" ]; then
|
||||
echo " 2. Run: node $OUTPUT_FILE"
|
||||
else
|
||||
echo " 2. Run: python3 $OUTPUT_FILE"
|
||||
fi
|
||||
echo
|
||||
|
||||
echo -e "${BLUE}💡 Tip: Check out the templates directory for more advanced examples${NC}"
|
||||
72
skills/inquirer-patterns/scripts/install-nodejs-deps.sh
Executable file
72
skills/inquirer-patterns/scripts/install-nodejs-deps.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
# install-nodejs-deps.sh
|
||||
# Install Node.js dependencies for inquirer patterns
|
||||
|
||||
set -e
|
||||
|
||||
echo "📦 Installing Node.js dependencies for inquirer patterns..."
|
||||
echo
|
||||
|
||||
# Check if npm is installed
|
||||
if ! command -v npm &> /dev/null; then
|
||||
echo "❌ Error: npm is not installed"
|
||||
echo "Please install Node.js and npm first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Node.js version
|
||||
NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
|
||||
if [ "$NODE_VERSION" -lt 14 ]; then
|
||||
echo "⚠️ Warning: Node.js 14 or higher is recommended"
|
||||
echo "Current version: $(node --version)"
|
||||
fi
|
||||
|
||||
# Create package.json if it doesn't exist
|
||||
if [ ! -f "package.json" ]; then
|
||||
echo "📝 Creating package.json..."
|
||||
cat > package.json << 'EOF'
|
||||
{
|
||||
"name": "inquirer-patterns-examples",
|
||||
"version": "1.0.0",
|
||||
"description": "Interactive prompt patterns for CLI tools",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": ["inquirer", "cli", "prompts", "interactive"],
|
||||
"author": "",
|
||||
"license": "MIT"
|
||||
}
|
||||
EOF
|
||||
echo "✅ package.json created"
|
||||
fi
|
||||
|
||||
# Install core dependencies
|
||||
echo "📥 Installing inquirer..."
|
||||
npm install inquirer@^9.0.0
|
||||
|
||||
echo "📥 Installing inquirer-autocomplete-prompt..."
|
||||
npm install inquirer-autocomplete-prompt@^3.0.0
|
||||
|
||||
# Optional: Install chalk for colored output
|
||||
echo "📥 Installing chalk (optional, for colored output)..."
|
||||
npm install chalk@^5.0.0
|
||||
|
||||
echo
|
||||
echo "✅ All Node.js dependencies installed successfully!"
|
||||
echo
|
||||
echo "📚 Installed packages:"
|
||||
echo " - inquirer@^9.0.0"
|
||||
echo " - inquirer-autocomplete-prompt@^3.0.0"
|
||||
echo " - chalk@^5.0.0"
|
||||
echo
|
||||
echo "🚀 You can now run the examples:"
|
||||
echo " node templates/nodejs/text-prompt.js"
|
||||
echo " node templates/nodejs/list-prompt.js"
|
||||
echo " node templates/nodejs/checkbox-prompt.js"
|
||||
echo " node templates/nodejs/password-prompt.js"
|
||||
echo " node templates/nodejs/autocomplete-prompt.js"
|
||||
echo " node templates/nodejs/conditional-prompt.js"
|
||||
echo " node templates/nodejs/comprehensive-example.js"
|
||||
echo
|
||||
65
skills/inquirer-patterns/scripts/install-python-deps.sh
Executable file
65
skills/inquirer-patterns/scripts/install-python-deps.sh
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
# install-python-deps.sh
|
||||
# Install Python dependencies for questionary patterns
|
||||
|
||||
set -e
|
||||
|
||||
echo "📦 Installing Python dependencies for questionary patterns..."
|
||||
echo
|
||||
|
||||
# Check if python3 is installed
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
echo "❌ Error: python3 is not installed"
|
||||
echo "Please install Python 3.7 or higher first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Python version
|
||||
PYTHON_VERSION=$(python3 --version | cut -d' ' -f2 | cut -d'.' -f1,2)
|
||||
MAJOR=$(echo $PYTHON_VERSION | cut -d'.' -f1)
|
||||
MINOR=$(echo $PYTHON_VERSION | cut -d'.' -f2)
|
||||
|
||||
if [ "$MAJOR" -lt 3 ] || ([ "$MAJOR" -eq 3 ] && [ "$MINOR" -lt 7 ]); then
|
||||
echo "⚠️ Warning: Python 3.7 or higher is recommended"
|
||||
echo "Current version: $(python3 --version)"
|
||||
fi
|
||||
|
||||
# Check if pip is installed
|
||||
if ! command -v pip3 &> /dev/null; then
|
||||
echo "❌ Error: pip3 is not installed"
|
||||
echo "Please install pip3 first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Upgrade pip
|
||||
echo "🔄 Upgrading pip..."
|
||||
python3 -m pip install --upgrade pip
|
||||
|
||||
# Install core dependencies
|
||||
echo "📥 Installing questionary..."
|
||||
pip3 install "questionary>=2.0.0"
|
||||
|
||||
echo "📥 Installing prompt_toolkit..."
|
||||
pip3 install "prompt_toolkit>=3.0.0"
|
||||
|
||||
# Optional: Install colorama for colored output on Windows
|
||||
echo "📥 Installing colorama (optional, for Windows support)..."
|
||||
pip3 install colorama
|
||||
|
||||
echo
|
||||
echo "✅ All Python dependencies installed successfully!"
|
||||
echo
|
||||
echo "📚 Installed packages:"
|
||||
echo " - questionary>=2.0.0"
|
||||
echo " - prompt_toolkit>=3.0.0"
|
||||
echo " - colorama"
|
||||
echo
|
||||
echo "🚀 You can now run the examples:"
|
||||
echo " python3 templates/python/text_prompt.py"
|
||||
echo " python3 templates/python/list_prompt.py"
|
||||
echo " python3 templates/python/checkbox_prompt.py"
|
||||
echo " python3 templates/python/password_prompt.py"
|
||||
echo " python3 templates/python/autocomplete_prompt.py"
|
||||
echo " python3 templates/python/conditional_prompt.py"
|
||||
echo
|
||||
206
skills/inquirer-patterns/scripts/validate-prompts.sh
Executable file
206
skills/inquirer-patterns/scripts/validate-prompts.sh
Executable file
@@ -0,0 +1,206 @@
|
||||
#!/bin/bash
|
||||
|
||||
# validate-prompts.sh
|
||||
# Validate prompt templates and check for common issues
|
||||
|
||||
set -e
|
||||
|
||||
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ERRORS=0
|
||||
WARNINGS=0
|
||||
|
||||
echo "🔍 Validating inquirer-patterns skill..."
|
||||
echo
|
||||
|
||||
# Color codes
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
error() {
|
||||
echo -e "${RED}❌ ERROR: $1${NC}"
|
||||
((ERRORS++))
|
||||
}
|
||||
|
||||
warning() {
|
||||
echo -e "${YELLOW}⚠️ WARNING: $1${NC}"
|
||||
((WARNINGS++))
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
# Check SKILL.md exists
|
||||
echo "📄 Checking SKILL.md..."
|
||||
if [ ! -f "$SKILL_DIR/SKILL.md" ]; then
|
||||
error "SKILL.md not found"
|
||||
else
|
||||
success "SKILL.md exists"
|
||||
|
||||
# Check frontmatter starts at line 1
|
||||
FIRST_LINE=$(head -n 1 "$SKILL_DIR/SKILL.md")
|
||||
if [ "$FIRST_LINE" != "---" ]; then
|
||||
error "SKILL.md frontmatter must start at line 1"
|
||||
else
|
||||
success "Frontmatter starts at line 1"
|
||||
fi
|
||||
|
||||
# Check for required frontmatter fields
|
||||
if ! grep -q "^name:" "$SKILL_DIR/SKILL.md"; then
|
||||
error "Missing 'name' field in frontmatter"
|
||||
else
|
||||
success "Frontmatter has 'name' field"
|
||||
fi
|
||||
|
||||
if ! grep -q "^description:" "$SKILL_DIR/SKILL.md"; then
|
||||
error "Missing 'description' field in frontmatter"
|
||||
else
|
||||
success "Frontmatter has 'description' field"
|
||||
fi
|
||||
|
||||
# Check for "Use when" context
|
||||
if ! grep -qi "use when" "$SKILL_DIR/SKILL.md"; then
|
||||
warning "Missing 'Use when' trigger context in description"
|
||||
else
|
||||
success "'Use when' context found"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Check Node.js templates
|
||||
echo "📁 Checking Node.js templates..."
|
||||
NODEJS_DIR="$SKILL_DIR/templates/nodejs"
|
||||
|
||||
if [ ! -d "$NODEJS_DIR" ]; then
|
||||
error "Node.js templates directory not found"
|
||||
else
|
||||
success "Node.js templates directory exists"
|
||||
|
||||
REQUIRED_NODEJS_TEMPLATES=(
|
||||
"text-prompt.js"
|
||||
"list-prompt.js"
|
||||
"checkbox-prompt.js"
|
||||
"password-prompt.js"
|
||||
"autocomplete-prompt.js"
|
||||
"conditional-prompt.js"
|
||||
"comprehensive-example.js"
|
||||
)
|
||||
|
||||
for template in "${REQUIRED_NODEJS_TEMPLATES[@]}"; do
|
||||
if [ ! -f "$NODEJS_DIR/$template" ]; then
|
||||
error "Missing Node.js template: $template"
|
||||
else
|
||||
# Check for basic syntax
|
||||
if ! grep -q "import inquirer from 'inquirer'" "$NODEJS_DIR/$template"; then
|
||||
if ! grep -q "inquirer" "$NODEJS_DIR/$template"; then
|
||||
warning "$template might be missing inquirer import"
|
||||
fi
|
||||
fi
|
||||
success "Node.js template exists: $template"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Check Python templates
|
||||
echo "📁 Checking Python templates..."
|
||||
PYTHON_DIR="$SKILL_DIR/templates/python"
|
||||
|
||||
if [ ! -d "$PYTHON_DIR" ]; then
|
||||
error "Python templates directory not found"
|
||||
else
|
||||
success "Python templates directory exists"
|
||||
|
||||
REQUIRED_PYTHON_TEMPLATES=(
|
||||
"text_prompt.py"
|
||||
"list_prompt.py"
|
||||
"checkbox_prompt.py"
|
||||
"password_prompt.py"
|
||||
"autocomplete_prompt.py"
|
||||
"conditional_prompt.py"
|
||||
)
|
||||
|
||||
for template in "${REQUIRED_PYTHON_TEMPLATES[@]}"; do
|
||||
if [ ! -f "$PYTHON_DIR/$template" ]; then
|
||||
error "Missing Python template: $template"
|
||||
else
|
||||
# Check for basic syntax
|
||||
if ! grep -q "import questionary" "$PYTHON_DIR/$template"; then
|
||||
warning "$template might be missing questionary import"
|
||||
fi
|
||||
success "Python template exists: $template"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Check scripts
|
||||
echo "📁 Checking scripts..."
|
||||
SCRIPTS_DIR="$SKILL_DIR/scripts"
|
||||
|
||||
REQUIRED_SCRIPTS=(
|
||||
"install-nodejs-deps.sh"
|
||||
"install-python-deps.sh"
|
||||
"validate-prompts.sh"
|
||||
"generate-prompt.sh"
|
||||
)
|
||||
|
||||
for script in "${REQUIRED_SCRIPTS[@]}"; do
|
||||
if [ ! -f "$SCRIPTS_DIR/$script" ]; then
|
||||
error "Missing script: $script"
|
||||
else
|
||||
if [ ! -x "$SCRIPTS_DIR/$script" ]; then
|
||||
warning "Script not executable: $script"
|
||||
else
|
||||
success "Script exists and is executable: $script"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
# Check for hardcoded API keys or secrets (security check)
|
||||
echo "🔒 Security check: Scanning for hardcoded secrets..."
|
||||
|
||||
# Patterns to search for
|
||||
SECRET_PATTERNS=(
|
||||
"sk-[a-zA-Z0-9]{32,}"
|
||||
"pk-[a-zA-Z0-9]{32,}"
|
||||
"AIza[0-9A-Za-z_-]{35}"
|
||||
"password.*=.*['\"][^'\"]{8,}['\"]"
|
||||
)
|
||||
|
||||
SECRETS_FOUND=0
|
||||
for pattern in "${SECRET_PATTERNS[@]}"; do
|
||||
if grep -rE "$pattern" "$SKILL_DIR/templates" 2>/dev/null | grep -v "your_.*_key_here" | grep -v "example" > /dev/null; then
|
||||
error "Potential hardcoded secret found matching pattern: $pattern"
|
||||
((SECRETS_FOUND++))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $SECRETS_FOUND -eq 0 ]; then
|
||||
success "No hardcoded secrets found"
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# Summary
|
||||
echo "═══════════════════════════════════════════════════════════"
|
||||
echo "Validation Summary"
|
||||
echo "═══════════════════════════════════════════════════════════"
|
||||
|
||||
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ All validations passed!${NC}"
|
||||
exit 0
|
||||
elif [ $ERRORS -eq 0 ]; then
|
||||
echo -e "${YELLOW}⚠️ Validation passed with $WARNINGS warning(s)${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}❌ Validation failed with $ERRORS error(s) and $WARNINGS warning(s)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user