@sconedev/ai_toolkit
Version:
Simplify AI integration in web apps with local and offline model support
246 lines (209 loc) ⢠7.37 kB
JavaScript
const inquirer = require('inquirer');
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
// Detect package manager
const useYarn = fs.existsSync(path.join(process.cwd(), 'yarn.lock'));
const packageManager = useYarn ? 'yarn' : 'npm';
// Feature configurations
const features = {
'core': {
name: 'Core AI Functionality',
description: 'Basic AI chat and text generation capabilities',
dependencies: [],
peerDependencies: [],
nodeOnly: false,
info: 'Core functionality for AI text generation',
installed: true, // Always installed
required: true
},
'pdf-processing': {
name: 'PDF Processing',
description: 'Extract text from PDFs and summarize content with AI',
dependencies: [],
peerDependencies: ['pdf-parse@1.1.1', 'pdfjs-dist'],
nodeOnly: false,
info: 'Allows summarizing PDF documents using AI',
installed: false,
required: false
},
'image-generation': {
name: 'Image Generation',
description: 'Generate images using AI',
dependencies: [],
peerDependencies: [],
nodeOnly: false,
info: 'Generate images using AI (requires OpenAI API access)',
installed: false,
required: false
}
};
// Load installed features
function loadInstalledFeatures() {
const configPath = path.join(process.cwd(), '.aitoolkit-features');
if (fs.existsSync(configPath)) {
const installedFeatureIds = fs.readFileSync(configPath, 'utf8')
.split('\n')
.filter(Boolean);
// Mark features as installed
installedFeatureIds.forEach(id => {
if (features[id]) {
features[id].installed = true;
}
});
}
}
// Save installed features
function saveInstalledFeatures() {
const installedFeatureIds = Object.keys(features)
.filter(id => features[id].installed);
const configPath = path.join(process.cwd(), '.aitoolkit-features');
fs.writeFileSync(configPath, installedFeatureIds.join('\n'), 'utf8');
}
async function main() {
console.log('\nš¤ AI Toolkit Feature Manager š¤\n');
// Load current state
loadInstalledFeatures();
const { action } = await inquirer.prompt([
{
type: 'list',
name: 'action',
message: 'What would you like to do?',
choices: [
{ name: 'Add new features', value: 'add' },
{ name: 'Remove features', value: 'remove' },
{ name: 'View installed features', value: 'view' },
{ name: 'Exit', value: 'exit' }
]
}
]);
if (action === 'exit') {
return;
}
if (action === 'view') {
console.log('\nCurrently installed features:');
const installedFeatures = Object.keys(features)
.filter(id => features[id].installed)
.map(id => features[id]);
if (installedFeatures.length === 0) {
console.log(' No features are currently installed.');
} else {
installedFeatures.forEach(feature => {
console.log(` ⢠${feature.name} - ${feature.description}`);
});
}
console.log('');
return main(); // Return to main menu
}
if (action === 'add') {
const availableFeatures = Object.keys(features)
.filter(id => !features[id].installed && !features[id].required)
.map(id => ({
name: `${features[id].name} - ${features[id].info}`,
value: id
}));
if (availableFeatures.length === 0) {
console.log('\nAll available features are already installed.\n');
return main(); // Return to main menu
}
const { featuresToAdd } = await inquirer.prompt([
{
type: 'checkbox',
name: 'featuresToAdd',
message: 'Select features to add:',
choices: availableFeatures
}
]);
if (featuresToAdd.length === 0) {
console.log('\nNo features selected.\n');
return main(); // Return to main menu
}
// Collect all dependencies to install
const dependencies = [];
const peerDependencies = [];
featuresToAdd.forEach(id => {
dependencies.push(...features[id].dependencies);
peerDependencies.push(...features[id].peerDependencies);
});
// Install dependencies
if (dependencies.length > 0) {
try {
console.log(`\nInstalling dependencies: ${dependencies.join(', ')}`);
execSync(`${packageManager} ${useYarn ? 'add' : 'install'} ${dependencies.join(' ')}`, {
stdio: 'inherit'
});
} catch (error) {
console.error('Failed to install dependencies:', error.message);
}
}
// Suggest peer dependencies
if (peerDependencies.length > 0) {
console.log('\nThe following peer dependencies are recommended for your selected features:');
console.log(` ${peerDependencies.join('\n ')}`);
const { installPeers } = await inquirer.prompt([
{
type: 'confirm',
name: 'installPeers',
message: 'Would you like to install these peer dependencies?',
default: true
}
]);
if (installPeers) {
try {
execSync(`${packageManager} ${useYarn ? 'add' : 'install'} ${peerDependencies.join(' ')}`, {
stdio: 'inherit'
});
} catch (error) {
console.error('Failed to install peer dependencies:', error.message);
}
}
}
// Mark features as installed
featuresToAdd.forEach(id => {
features[id].installed = true;
});
// Save installed features
saveInstalledFeatures();
console.log('\nā
Features added successfully!\n');
return main(); // Return to main menu
}
if (action === 'remove') {
const removableFeatures = Object.keys(features)
.filter(id => features[id].installed && !features[id].required)
.map(id => ({
name: `${features[id].name} - ${features[id].info}`,
value: id
}));
if (removableFeatures.length === 0) {
console.log('\nNo removable features are currently installed.\n');
return main(); // Return to main menu
}
const { featuresToRemove } = await inquirer.prompt([
{
type: 'checkbox',
name: 'featuresToRemove',
message: 'Select features to remove:',
choices: removableFeatures
}
]);
if (featuresToRemove.length === 0) {
console.log('\nNo features selected.\n');
return main(); // Return to main menu
}
// Mark features as not installed
featuresToRemove.forEach(id => {
features[id].installed = false;
});
// Save installed features
saveInstalledFeatures();
console.log('\nā
Features removed successfully!');
console.log('Note: Dependencies were not removed. If you want to remove unused dependencies,');
console.log(`you can do so manually with '${packageManager} ${useYarn ? 'remove' : 'uninstall'} <package-name>'.\n`);
return main(); // Return to main menu
}
}
main().catch(error => {
console.error('An error occurred:', error);
process.exit(1);
});