UNPKG

@neuroequality/neuroadapt-cli

Version:

CLI tool for creating accessible quantum and VR applications

1,348 lines (1,259 loc) • 64.1 kB
#!/usr/bin/env node import { Command } from "commander"; import chalk from "chalk"; import { c as createApp } from "./create-app-Bhc4KAlH.js"; import inquirer from "inquirer"; import ora from "ora"; import fs from "fs-extra"; import * as path from "path"; import path__default from "path"; async function createQuantumApp(name, options = { template: "basic" }) { console.log(chalk.blue("āš›ļø Creating NeuroAdapt Quantum Application\n")); let appName = name; if (!appName) { const { selectedName } = await inquirer.prompt([ { type: "input", name: "selectedName", message: "Application name:", validate: (input) => { if (!input) return "Please provide an application name"; if (!/^[a-z0-9-_]+$/i.test(input)) return "Name can only contain letters, numbers, hyphens, and underscores"; return true; } } ]); appName = selectedName; } const spinner = ora("Creating quantum application...").start(); try { const projectRoot = path.join(process.cwd(), appName); if (await fs.pathExists(projectRoot)) { spinner.fail(`Directory '${appName}' already exists`); return; } spinner.text = "Setting up project structure..."; await fs.ensureDir(projectRoot); spinner.stop(); const answers = await inquirer.prompt([ { type: "list", name: "template", message: "Choose a quantum template:", choices: [ { name: "Basic Quantum Circuits", value: "basic" }, { name: "Bloch Sphere Visualization", value: "bloch" }, { name: "Quantum Algorithm Demo", value: "algorithm" }, { name: "Educational Quantum Simulator", value: "educational" } ], when: !options.template }, { type: "confirm", name: "typescript", message: "Use TypeScript?", default: true, when: options.typescript === void 0 }, { type: "checkbox", name: "accessibility", message: "Select accessibility features:", choices: [ { name: "Screen Reader Support", value: "screenreader", checked: true }, { name: "Keyboard Navigation", value: "keyboard", checked: true }, { name: "High Contrast Mode", value: "contrast", checked: true }, { name: "Motion Reduction", value: "motion", checked: true }, { name: "Audio Descriptions", value: "audio", checked: false } ] } ]); const template = options.template || answers.template; const useTypeScript = options.typescript ?? answers.typescript; const accessibilityFeatures = answers.accessibility; const creationSpinner = ora("Generating quantum application...").start(); const packageJson = { name: appName, version: "1.0.0", description: `Accessible quantum computing application - ${template} template`, main: useTypeScript ? "dist/index.js" : "src/index.js", scripts: { dev: useTypeScript ? "tsc && node dist/index.js" : "node src/index.js", build: useTypeScript ? "tsc" : 'echo "No build step needed"', start: useTypeScript ? "node dist/index.js" : "node src/index.js", test: "npm run test:unit && npm run test:accessibility", "test:unit": "jest", "test:accessibility": "playwright test tests/accessibility" }, dependencies: { "@neuroadapt/core": "^1.1.0", "@neuroadapt/quantum": "^1.1.0", "@neuroadapt/testing": "^1.1.0" }, devDependencies: useTypeScript ? { "typescript": "^5.0.0", "@types/node": "^20.0.0", "jest": "^29.0.0", "@playwright/test": "^1.40.0" } : { "jest": "^29.0.0", "@playwright/test": "^1.40.0" } }; await fs.writeJson(path.join(projectRoot, "package.json"), packageJson, { spaces: 2 }); if (useTypeScript) { const tsConfig = { compilerOptions: { target: "ES2020", module: "commonjs", outDir: "./dist", rootDir: "./src", strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, declaration: true, declarationMap: true, sourceMap: true }, include: ["src/**/*"], exclude: ["node_modules", "dist", "tests"] }; await fs.writeJson(path.join(projectRoot, "tsconfig.json"), tsConfig, { spaces: 2 }); } const srcDir = path.join(projectRoot, "src"); await fs.ensureDir(srcDir); const mainContent = generateMainApp(template, accessibilityFeatures, useTypeScript); await fs.writeFile( path.join(srcDir, `index.${useTypeScript ? "ts" : "js"}`), mainContent ); switch (template) { case "bloch": const blochContent = generateBlochSphereInit(useTypeScript); await fs.writeFile( path.join(srcDir, `bloch-sphere.${useTypeScript ? "ts" : "js"}`), blochContent ); break; case "algorithm": const algorithmContent = generateQuantumAlgorithm(useTypeScript); await fs.writeFile( path.join(srcDir, `quantum-algorithm.${useTypeScript ? "ts" : "js"}`), algorithmContent ); break; case "educational": const educationalContent = generateEducationalSimulator(useTypeScript); await fs.writeFile( path.join(srcDir, `quantum-simulator.${useTypeScript ? "ts" : "js"}`), educationalContent ); break; default: const circuitContent = generateCircuitBuilderInit(useTypeScript); await fs.writeFile( path.join(srcDir, `quantum-circuit.${useTypeScript ? "ts" : "js"}`), circuitContent ); } const accessibilityConfig = { quantum: { visualizations: { colorBlindFriendly: accessibilityFeatures.includes("contrast"), highContrast: accessibilityFeatures.includes("contrast"), reduceMotion: accessibilityFeatures.includes("motion"), audioDescriptions: accessibilityFeatures.includes("audio") }, interactions: { keyboardNavigation: accessibilityFeatures.includes("keyboard"), screenReaderSupport: accessibilityFeatures.includes("screenreader"), alternativeInputs: true } } }; await fs.writeJson( path.join(projectRoot, "accessibility.config.json"), accessibilityConfig, { spaces: 2 } ); const readmeContent = generateReadme(appName, template, useTypeScript, accessibilityFeatures); await fs.writeFile(path.join(projectRoot, "README.md"), readmeContent); creationSpinner.succeed("Quantum application created successfully!"); console.log(chalk.green("\nāœ… Success! Your accessible quantum app is ready:")); console.log(chalk.gray(`šŸ“ Directory: ${appName}`)); console.log(chalk.gray(`āš›ļø Template: ${template}`)); console.log(chalk.gray(`šŸ“ Language: ${useTypeScript ? "TypeScript" : "JavaScript"}`)); console.log(chalk.gray(`♿ Accessibility: ${accessibilityFeatures.join(", ")}`)); console.log(chalk.blue("\nšŸ’” Next steps:")); console.log(chalk.gray(`1. cd ${appName}`)); console.log(chalk.gray("2. npm install")); console.log(chalk.gray("3. npm run dev")); } catch (error) { spinner.fail("Failed to create quantum application"); console.error(chalk.red(error instanceof Error ? error.message : "Unknown error")); process.exit(1); } } function generateBlochSphereInit(isTS) { const typeAnnotation = isTS ? ": void" : ""; return `/** * Bloch Sphere Visualization - Accessible quantum state visualization */ import { BlochSphere } from '@neuroadapt/quantum'; import { PreferenceStore } from '@neuroadapt/core'; const preferences = new PreferenceStore({ key: 'quantum-prefs' }); export async function initializeBlochSphere()${typeAnnotation} { const userPrefs = await preferences.load(); const sphere = new BlochSphere({ container: '#bloch-container', accessibility: { colorBlindFriendly: userPrefs?.sensory?.colorVisionFilter !== 'none', highContrast: userPrefs?.sensory?.highContrast || false, screenReaderDescriptions: true, keyboardControls: userPrefs?.motor?.keyboardNavigation || false } }); // Add quantum state sphere.setState([0.6, 0.8]); // |0⟩ + |1⟩ superposition // Enable accessibility features sphere.enableKeyboardNavigation(); sphere.addScreenReaderDescriptions(); return sphere; } `; } function generateCircuitBuilderInit(isTS) { const typeAnnotation = isTS ? ": void" : ""; return `/** * Quantum Circuit Builder - Accessible quantum circuit construction */ import { QuantumCircuit } from '@neuroadapt/quantum'; import { PreferenceStore } from '@neuroadapt/core'; const preferences = new PreferenceStore({ key: 'quantum-prefs' }); export async function initializeCircuitBuilder()${typeAnnotation} { const userPrefs = await preferences.load(); const circuit = new QuantumCircuit(3); // 3-qubit circuit // Configure accessibility circuit.setAccessibilityOptions({ keyboardNavigation: userPrefs?.motor?.keyboardNavigation || false, screenReaderSupport: true, highContrast: userPrefs?.sensory?.highContrast || false, reduceAnimations: userPrefs?.sensory?.motionReduction || false }); // Add some basic gates circuit.addGate('H', 0); // Hadamard gate on qubit 0 circuit.addGate('CNOT', [0, 1]); // CNOT gate between qubits 0 and 1 circuit.addGate('H', 2); // Hadamard gate on qubit 2 // Render circuit with accessibility features circuit.render('#circuit-container'); return circuit; } `; } function generateMainApp(template, features, isTS) { return `/** * ${template.charAt(0).toUpperCase() + template.slice(1)} Quantum Application * Accessible quantum computing with NeuroAdapt SDK */ import { PreferenceStore } from '@neuroadapt/core'; ${template === "bloch" ? "import { initializeBlochSphere } from './bloch-sphere';" : ""} ${template === "basic" ? "import { initializeCircuitBuilder } from './quantum-circuit';" : ""} const preferences = new PreferenceStore({ key: 'quantum-app-prefs' }); async function main()${isTS ? ": Promise<void>" : ""} { console.log('šŸš€ Starting Accessible Quantum Application'); try { // Load user preferences const userPrefs = await preferences.load(); console.log('šŸ“‹ User preferences loaded'); // Apply accessibility settings applyAccessibilitySettings(userPrefs); // Initialize quantum components ${template === "bloch" ? "await initializeBlochSphere();" : ""} ${template === "basic" ? "await initializeCircuitBuilder();" : ""} console.log('āœ… Quantum application ready!'); } catch (error) { console.error('āŒ Failed to initialize application:', error); } } function applyAccessibilitySettings(prefs${isTS ? ": any" : ""}) { if (prefs?.sensory?.highContrast) { document.body.classList.add('high-contrast'); } if (prefs?.sensory?.motionReduction) { document.body.classList.add('reduce-motion'); } if (prefs?.motor?.keyboardNavigation) { document.body.classList.add('keyboard-navigation'); } } // Start the application main().catch(console.error); `; } function generateQuantumAlgorithm(isTS) { return `/** * Quantum Algorithm Implementation - Accessible quantum algorithms */ import { QuantumCircuit } from '@neuroadapt/quantum'; export class AccessibleQuantumAlgorithm { private circuit${isTS ? ": QuantumCircuit" : ""}; constructor(qubits${isTS ? ": number" : ""}) { this.circuit = new QuantumCircuit(qubits); } // Implement Deutsch-Jozsa algorithm with accessibility deutschJozsa()${isTS ? ": void" : ""} { console.log('šŸ”¬ Running Deutsch-Jozsa Algorithm'); // Step 1: Initialize qubits this.circuit.addGate('H', 0); // Hadamard on first qubit this.circuit.addGate('X', 1); // X gate on second qubit this.circuit.addGate('H', 1); // Hadamard on second qubit // Step 2: Apply oracle (placeholder) this.circuit.addGate('CNOT', [0, 1]); // Step 3: Final Hadamard this.circuit.addGate('H', 0); // Measure and describe result const result = this.circuit.measure(); this.announceResult(result); } private announceResult(result${isTS ? ": any" : ""})${isTS ? ": void" : ""} { const description = result === 0 ? 'Function is constant - all inputs produce the same output' : 'Function is balanced - inputs produce different outputs'; console.log(\`šŸ“Š Result: \${description}\`); // Add screen reader announcement if (typeof window !== 'undefined') { const announcement = document.createElement('div'); announcement.setAttribute('aria-live', 'polite'); announcement.textContent = description; document.body.appendChild(announcement); } } } `; } function generateEducationalSimulator(isTS) { return `/** * Educational Quantum Simulator - Learning-focused quantum computing */ import { QuantumCircuit } from '@neuroadapt/quantum'; export class EducationalQuantumSimulator { private circuit${isTS ? ": QuantumCircuit" : ""}; private stepCount${isTS ? ": number" : ""} = 0; constructor() { this.circuit = new QuantumCircuit(2); } // Interactive quantum gate exploration exploreGates()${isTS ? ": void" : ""} { console.log('šŸ“š Welcome to Quantum Gate Explorer'); console.log('Press keys to add gates: H (Hadamard), X (Pauli-X), C (CNOT)'); if (typeof window !== 'undefined') { document.addEventListener('keydown', this.handleKeyPress.bind(this)); } } private handleKeyPress(event${isTS ? ": KeyboardEvent" : ""})${isTS ? ": void" : ""} { switch (event.key.toLowerCase()) { case 'h': this.addHadamardGate(); break; case 'x': this.addPauliXGate(); break; case 'c': this.addCNOTGate(); break; case 'r': this.resetCircuit(); break; } } private addHadamardGate()${isTS ? ": void" : ""} { this.circuit.addGate('H', 0); this.announceStep('Added Hadamard gate - creates superposition'); } private addPauliXGate()${isTS ? ": void" : ""} { this.circuit.addGate('X', 0); this.announceStep('Added Pauli-X gate - flips qubit state'); } private addCNOTGate()${isTS ? ": void" : ""} { this.circuit.addGate('CNOT', [0, 1]); this.announceStep('Added CNOT gate - creates entanglement'); } private resetCircuit()${isTS ? ": void" : ""} { this.circuit = new QuantumCircuit(2); this.stepCount = 0; this.announceStep('Circuit reset'); } private announceStep(description${isTS ? ": string" : ""})${isTS ? ": void" : ""} { this.stepCount++; console.log(\`Step \${this.stepCount}: \${description}\`); // Screen reader announcement if (typeof window !== 'undefined') { const announcement = document.createElement('div'); announcement.setAttribute('aria-live', 'polite'); announcement.textContent = \`Step \${this.stepCount}: \${description}\`; document.body.appendChild(announcement); // Clean up old announcements setTimeout(() => announcement.remove(), 3000); } } } `; } function generateReadme(appName, template, isTS, features) { return `# ${appName} An accessible quantum computing application built with NeuroAdapt SDK. ## Features - **Template**: ${template} - **Language**: ${isTS ? "TypeScript" : "JavaScript"} - **Accessibility**: ${features.join(", ")} - **Quantum Computing**: Circuit simulation, visualization, and algorithms ## Quick Start \`\`\`bash npm install npm run dev \`\`\` ## Accessibility Features This application includes comprehensive accessibility support: ${features.includes("screenreader") ? "- **Screen Reader Support**: All quantum states and operations are announced\n" : ""} ${features.includes("keyboard") ? "- **Keyboard Navigation**: Full keyboard control of quantum circuits\n" : ""} ${features.includes("contrast") ? "- **High Contrast Mode**: Enhanced visibility for quantum visualizations\n" : ""} ${features.includes("motion") ? "- **Motion Reduction**: Reduced animations for motion sensitivity\n" : ""} ${features.includes("audio") ? "- **Audio Descriptions**: Spoken descriptions of quantum operations\n" : ""} ## Usage ### Basic Quantum Circuit \`\`\`${isTS ? "typescript" : "javascript"} import { QuantumCircuit } from '@neuroadapt/quantum'; const circuit = new QuantumCircuit(2); circuit.addGate('H', 0); // Hadamard gate circuit.addGate('CNOT', [0, 1]); // CNOT gate circuit.render('#circuit-container'); \`\`\` ### Accessibility Configuration \`\`\`${isTS ? "typescript" : "javascript"} circuit.setAccessibilityOptions({ keyboardNavigation: true, screenReaderSupport: true, highContrast: false, reduceAnimations: false }); \`\`\` ## Keyboard Shortcuts - **H**: Add Hadamard gate - **X**: Add Pauli-X gate - **C**: Add CNOT gate - **R**: Reset circuit - **Tab**: Navigate between elements - **Enter/Space**: Activate controls ## Learn More - [NeuroAdapt SDK Documentation](https://neuroadapt.dev) - [Quantum Computing Basics](https://neuroadapt.dev/quantum) - [Accessibility Guidelines](https://neuroadapt.dev/accessibility) ## Support For accessibility support or quantum computing questions, visit our [documentation](https://neuroadapt.dev) or open an issue. `; } async function createVRApp(name, options = { template: "basic" }) { console.log(chalk.blue("🄽 Creating NeuroAdapt VR Application\n")); let appName = name; if (!appName) { const { selectedName } = await inquirer.prompt([ { type: "input", name: "selectedName", message: "VR Application name:", validate: (input) => { if (!input) return "Please provide an application name"; if (!/^[a-z0-9-_]+$/i.test(input)) return "Name can only contain letters, numbers, hyphens, and underscores"; return true; } } ]); appName = selectedName; } const spinner = ora("Creating VR application...").start(); try { const projectRoot = path.join(process.cwd(), appName); if (await fs.pathExists(projectRoot)) { spinner.fail(`Directory '${appName}' already exists`); return; } spinner.text = "Setting up VR project structure..."; await fs.ensureDir(projectRoot); spinner.stop(); const answers = await inquirer.prompt([ { type: "list", name: "template", message: "Choose a VR template:", choices: [ { name: "Basic VR Experience", value: "basic" }, { name: "Safe Zone Demo", value: "safezone" }, { name: "Proximity Detection", value: "proximity" }, { name: "Educational VR Environment", value: "educational" }, { name: "Therapy/Meditation VR", value: "therapy" } ], when: !options.template }, { type: "list", name: "platform", message: "Target VR platform:", choices: [ { name: "WebXR (Browser)", value: "webxr" }, { name: "Unity", value: "unity" }, { name: "Unreal Engine", value: "unreal" }, { name: "A-Frame", value: "aframe" } ], when: !options.platform }, { type: "confirm", name: "typescript", message: "Use TypeScript?", default: true, when: options.typescript === void 0 }, { type: "checkbox", name: "safetyFeatures", message: "Select safety and accessibility features:", choices: [ { name: "Safe Zone Management", value: "safezone", checked: true }, { name: "Proximity Detection", value: "proximity", checked: true }, { name: "Motion Sickness Prevention", value: "motion", checked: true }, { name: "Emergency Panic Mode", value: "panic", checked: true }, { name: "Audio Spatial Warnings", value: "audio", checked: true }, { name: "Haptic Feedback Alerts", value: "haptic", checked: false } ] } ]); const template = options.template || answers.template; const platform = options.platform || answers.platform; const useTypeScript = options.typescript ?? answers.typescript; const safetyFeatures = answers.safetyFeatures; const creationSpinner = ora("Generating VR application...").start(); const packageJson = { name: appName, version: "1.0.0", description: `Accessible VR application - ${template} template for ${platform}`, main: useTypeScript ? "dist/index.js" : "src/index.js", scripts: { dev: platform === "webxr" ? "vite dev" : useTypeScript ? "tsc && node dist/index.js" : "node src/index.js", build: platform === "webxr" ? "vite build" : useTypeScript ? "tsc" : 'echo "No build step needed"', start: useTypeScript ? "node dist/index.js" : "node src/index.js", preview: platform === "webxr" ? "vite preview" : "npm start", test: "npm run test:unit && npm run test:accessibility", "test:unit": "jest", "test:accessibility": "playwright test tests/accessibility" }, dependencies: { "@neuroadapt/core": "^1.1.0", "@neuroadapt/vr": "^1.1.0", "@neuroadapt/testing": "^1.1.0" }, devDependencies: {} }; if (platform === "webxr") { packageJson.dependencies["three"] = "^0.160.0"; packageJson.dependencies["aframe"] = "^1.4.0"; packageJson.devDependencies["vite"] = "^5.0.0"; } if (useTypeScript) { packageJson.devDependencies["typescript"] = "^5.0.0"; packageJson.devDependencies["@types/node"] = "^20.0.0"; if (platform === "webxr") { packageJson.devDependencies["@types/three"] = "^0.160.0"; packageJson.devDependencies["@types/aframe"] = "^1.2.0"; } } packageJson.devDependencies["jest"] = "^29.0.0"; packageJson.devDependencies["@playwright/test"] = "^1.40.0"; await fs.writeJson(path.join(projectRoot, "package.json"), packageJson, { spaces: 2 }); if (useTypeScript) { const tsConfig = { compilerOptions: { target: "ES2020", module: platform === "webxr" ? "ESNext" : "commonjs", moduleResolution: "bundler", outDir: "./dist", rootDir: "./src", strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, declaration: true, declarationMap: true, sourceMap: true, types: platform === "webxr" ? ["vite/client"] : ["node"] }, include: ["src/**/*"], exclude: ["node_modules", "dist", "tests"] }; await fs.writeJson(path.join(projectRoot, "tsconfig.json"), tsConfig, { spaces: 2 }); } if (platform === "webxr") { const viteConfig = `import { defineConfig } from 'vite'; export default defineConfig({ server: { https: true, // Required for WebXR port: 3000 }, build: { target: 'esnext' } });`; await fs.writeFile(path.join(projectRoot, "vite.config.js"), viteConfig); } const srcDir = path.join(projectRoot, "src"); await fs.ensureDir(srcDir); const mainContent = this.generateMainVRApp(template, platform, safetyFeatures, useTypeScript); await fs.writeFile( path.join(srcDir, `index.${useTypeScript ? "ts" : "js"}`), mainContent ); switch (template) { case "safezone": const safeZoneContent = this.generateSafeZoneSetup(useTypeScript); await fs.writeFile( path.join(srcDir, `safe-zone-manager.${useTypeScript ? "ts" : "js"}`), safeZoneContent ); break; case "proximity": const proximityContent = this.generateProximitySetup(useTypeScript); await fs.writeFile( path.join(srcDir, `proximity-detector.${useTypeScript ? "ts" : "js"}`), proximityContent ); break; case "therapy": const therapyContent = this.generateTherapyEnvironment(useTypeScript); await fs.writeFile( path.join(srcDir, `therapy-environment.${useTypeScript ? "ts" : "js"}`), therapyContent ); break; case "educational": const educationalContent = this.generateEducationalVR(useTypeScript); await fs.writeFile( path.join(srcDir, `educational-vr.${useTypeScript ? "ts" : "js"}`), educationalContent ); break; } if (platform === "webxr") { const htmlContent = this.generateWebXRHTML(appName, template); await fs.writeFile(path.join(projectRoot, "index.html"), htmlContent); } const safetyConfig = { vr: { safety: { safeZoneEnabled: safetyFeatures.includes("safezone"), proximityDetection: safetyFeatures.includes("proximity"), motionSicknessReduction: safetyFeatures.includes("motion"), panicMode: safetyFeatures.includes("panic"), spatialAudio: safetyFeatures.includes("audio"), hapticFeedback: safetyFeatures.includes("haptic") }, boundaries: { width: 2, // meters height: 2, depth: 2 }, comfort: { locomotionType: "teleport", turnType: "snap", vignettingEnabled: true } } }; await fs.writeJson( path.join(projectRoot, "vr-safety.config.json"), safetyConfig, { spaces: 2 } ); const readmeContent = this.generateVRReadme(appName, template, platform, useTypeScript, safetyFeatures); await fs.writeFile(path.join(projectRoot, "README.md"), readmeContent); creationSpinner.succeed("VR application created successfully!"); console.log(chalk.green("\nāœ… Success! Your accessible VR app is ready:")); console.log(chalk.gray(`šŸ“ Directory: ${appName}`)); console.log(chalk.gray(`🄽 Template: ${template}`)); console.log(chalk.gray(`šŸŽ® Platform: ${platform}`)); console.log(chalk.gray(`šŸ“ Language: ${useTypeScript ? "TypeScript" : "JavaScript"}`)); console.log(chalk.gray(`šŸ›”ļø Safety: ${safetyFeatures.join(", ")}`)); console.log(chalk.blue("\nšŸ’” Next steps:")); console.log(chalk.gray(`1. cd ${appName}`)); console.log(chalk.gray("2. npm install")); console.log(chalk.gray("3. npm run dev")); if (platform === "webxr") { console.log(chalk.yellow("\nāš ļø WebXR Notes:")); console.log(chalk.gray("• Requires HTTPS for VR features")); console.log(chalk.gray("• Test on VR-capable devices")); console.log(chalk.gray("• Configure safe zone before use")); } } catch (error) { spinner.fail("Failed to create VR application"); console.error(chalk.red(error instanceof Error ? error.message : "Unknown error")); process.exit(1); } } async function addAdapter(adapterType, options = {}) { console.log(chalk.blue("šŸ”§ Adding NeuroAdapt Accessibility Adapter\n")); let adapter = adapterType; if (!adapter) { const { selectedAdapter } = await inquirer.prompt([ { type: "list", name: "selectedAdapter", message: "Which adapter would you like to add?", choices: [ { name: "OpenAI Adapter", value: "openai" }, { name: "Claude Adapter", value: "claude" }, { name: "Ollama Adapter", value: "ollama" }, { name: "All Adapters", value: "all" } ] } ]); adapter = selectedAdapter; } const spinner = ora("Adding adapter configuration...").start(); try { const projectRoot = process.cwd(); const packageJsonPath = path__default.join(projectRoot, "package.json"); if (!await fs.pathExists(packageJsonPath)) { spinner.fail("No package.json found. Please run this command in a project directory."); return; } const packageJson = await fs.readJson(packageJsonPath); const dependencies = packageJson.dependencies || {}; const devDependencies = packageJson.devDependencies || {}; dependencies["@neuroadapt/ai"] = "^1.1.0"; if (adapter === "openai" || adapter === "all") { dependencies["openai"] = "^4.0.0"; } if (adapter === "claude" || adapter === "all") { dependencies["@anthropic-ai/sdk"] = "^0.20.0"; } if (adapter === "ollama" || adapter === "all") { dependencies["ollama"] = "^0.5.0"; } packageJson.dependencies = dependencies; packageJson.devDependencies = devDependencies; await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 }); const configPath = path__default.join(projectRoot, "neuroadapt.config.js"); if (!await fs.pathExists(configPath) || options.force) { const configContent = generateAdapterConfig(adapter); await fs.writeFile(configPath, configContent); } const examplePath = path__default.join(projectRoot, "src", "neuroadapt-example.ts"); await fs.ensureDir(path__default.dirname(examplePath)); if (!await fs.pathExists(examplePath) || options.force) { const exampleContent = generateExampleUsage(adapter); await fs.writeFile(examplePath, exampleContent); } spinner.succeed("Adapter configuration added successfully!"); console.log(chalk.green("\nāœ… Success! Next steps:")); console.log(chalk.gray("1. Run `npm install` or `pnpm install` to install dependencies")); console.log(chalk.gray("2. Configure your API keys in environment variables")); console.log(chalk.gray("3. Check `src/neuroadapt-example.ts` for usage examples")); } catch (error) { spinner.fail("Failed to add adapter configuration"); console.error(chalk.red(error instanceof Error ? error.message : "Unknown error")); process.exit(1); } } function generateAdapterConfig(adapter) { return `/** * NeuroAdapt Configuration * Configure accessibility adapters for your application */ export default { adapters: { ${adapter === "openai" || adapter === "all" ? ` openai: { apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4', features: ['cognitive-assistance', 'content-adaptation'] },` : ""} ${adapter === "claude" || adapter === "all" ? ` claude: { apiKey: process.env.ANTHROPIC_API_KEY, model: 'claude-3-sonnet-20240229', features: ['cognitive-assistance', 'content-simplification'] },` : ""} ${adapter === "ollama" || adapter === "all" ? ` ollama: { baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434', model: 'llama2', features: ['local-processing', 'privacy-focused'] },` : ""} }, accessibility: { cognitive: { enabled: true, adaptationLevel: 'medium', processingPace: 'normal' }, sensory: { enabled: true, highContrast: false, motionReduction: false, fontSize: 16 }, motor: { enabled: true, keyboardNavigation: true, largerTargets: false } } }; `; } function generateExampleUsage(adapter) { return `/** * NeuroAdapt Usage Example * Example implementation of accessibility adapters */ import { createAdapter } from '@neuroadapt/ai'; import { PreferenceStore } from '@neuroadapt/core'; import config from '../neuroadapt.config.js'; // Initialize preference store const preferences = new PreferenceStore({ key: 'neuroadapt-prefs' }); // Create adapter based on configuration ${adapter === "openai" || adapter === "all" ? ` // OpenAI Adapter Example const openaiAdapter = createAdapter('openai', { apiKey: config.adapters.openai?.apiKey, model: config.adapters.openai?.model }); ` : ""} ${adapter === "claude" || adapter === "all" ? ` // Claude Adapter Example const claudeAdapter = createAdapter('claude', { apiKey: config.adapters.claude?.apiKey, model: config.adapters.claude?.model }); ` : ""} ${adapter === "ollama" || adapter === "all" ? ` // Ollama Adapter Example const ollamaAdapter = createAdapter('ollama', { baseUrl: config.adapters.ollama?.baseUrl, model: config.adapters.ollama?.model }); ` : ""} // Example: Adapt content for cognitive accessibility export async function adaptContentForUser(content: string) { try { const userPrefs = await preferences.load(); if (userPrefs?.cognitive.explanationLevel === 'simple') { ${adapter === "openai" ? "const result = await openaiAdapter.simplifyContent(content);" : adapter === "claude" ? "const result = await claudeAdapter.simplifyContent(content);" : adapter === "ollama" ? "const result = await ollamaAdapter.simplifyContent(content);" : "const result = await openaiAdapter.simplifyContent(content);"} return result.adaptedContent; } return content; } catch (error) { console.error('Content adaptation failed:', error); return content; // Fallback to original content } } // Example: Get personalized accessibility recommendations export async function getAccessibilityRecommendations() { try { const userPrefs = await preferences.load(); ${adapter === "openai" ? "const recommendations = await openaiAdapter.getRecommendations(userPrefs);" : adapter === "claude" ? "const recommendations = await claudeAdapter.getRecommendations(userPrefs);" : adapter === "ollama" ? "const recommendations = await ollamaAdapter.getRecommendations(userPrefs);" : "const recommendations = await openaiAdapter.getRecommendations(userPrefs);"} return recommendations; } catch (error) { console.error('Failed to get recommendations:', error); return []; } } `; } async function exportProfile(profileName, options = {}) { console.log(chalk.blue("šŸ“¤ Exporting NeuroAdapt Accessibility Profile\n")); const spinner = ora("Scanning for accessibility profiles...").start(); try { const projectRoot = process.cwd(); const preferencesPath = path__default.join(projectRoot, ".neuroadapt", "preferences.json"); const configPath = path__default.join(projectRoot, "neuroadapt.config.js"); if (!await fs.pathExists(preferencesPath)) { spinner.fail("No accessibility preferences found in this project."); console.log(chalk.gray("Run your application first to generate preferences, or use `neuroadapt create-app` to start fresh.")); return; } spinner.text = "Loading preferences..."; const preferences = await fs.readJson(preferencesPath); let config = {}; if (await fs.pathExists(configPath)) { const configModule = await import(path__default.resolve(configPath)); config = configModule.default || configModule; } spinner.stop(); let format = options.format; let outputPath = options.output; let includePersonalData = options.includePersonalData; if (!format || !outputPath) { const answers = await inquirer.prompt([ { type: "list", name: "format", message: "Export format:", choices: [ { name: "JSON (recommended)", value: "json" }, { name: "JavaScript/ES Module", value: "js" }, { name: "YAML", value: "yaml" } ], when: !format }, { type: "input", name: "outputPath", message: "Output file path:", default: `accessibility-profile.${format || "json"}`, when: !outputPath }, { type: "confirm", name: "includePersonalData", message: "Include personal data (usage analytics, session data)?", default: false, when: includePersonalData === void 0 } ]); format = format || answers.format; outputPath = outputPath || answers.outputPath; includePersonalData = includePersonalData ?? answers.includePersonalData; } const exportSpinner = ora("Generating profile export...").start(); const profile = createExportableProfile(preferences, config, includePersonalData); let content; const resolvedOutputPath = path__default.resolve(outputPath); switch (format) { case "json": content = JSON.stringify(profile, null, 2); break; case "js": content = generateJSExport(profile); break; case "yaml": content = generateYAMLExport(profile); break; default: throw new Error(`Unsupported format: ${format}`); } await fs.ensureDir(path__default.dirname(resolvedOutputPath)); await fs.writeFile(resolvedOutputPath, content, "utf8"); exportSpinner.succeed("Profile exported successfully!"); console.log(chalk.green("\nāœ… Export completed:")); console.log(chalk.gray(`šŸ“ File: ${resolvedOutputPath}`)); console.log(chalk.gray(`šŸ“Š Format: ${format?.toUpperCase()}`)); console.log(chalk.gray(`šŸ”’ Personal data: ${includePersonalData ? "Included" : "Excluded"}`)); console.log(chalk.blue("\nšŸ’” Usage:")); console.log(chalk.gray("• Share this profile with other developers")); console.log(chalk.gray("• Import it using `neuroadapt import-profile`")); console.log(chalk.gray("• Use it as a template for new projects")); } catch (error) { spinner.fail("Failed to export profile"); console.error(chalk.red(error instanceof Error ? error.message : "Unknown error")); process.exit(1); } } function createExportableProfile(preferences, config, includePersonalData) { const profile = { name: preferences.name || "Accessibility Profile", version: "1.1.0", createdAt: (/* @__PURE__ */ new Date()).toISOString(), accessibility: { cognitive: { readingSpeed: preferences.cognitive?.readingSpeed || "normal", processingPace: preferences.cognitive?.processingPace || "normal", explanationLevel: preferences.cognitive?.explanationLevel || "standard", allowInterruptions: preferences.cognitive?.allowInterruptions ?? true }, sensory: { highContrast: preferences.sensory?.highContrast || false, darkMode: preferences.sensory?.darkMode || false, motionReduction: preferences.sensory?.motionReduction || false, fontSize: preferences.sensory?.fontSize || 16, colorVisionFilter: preferences.sensory?.colorVisionFilter || "none" }, motor: { keyboardNavigation: preferences.motor?.keyboardNavigation || false, mouseAlternatives: preferences.motor?.mouseAlternatives || false, targetSizeIncrease: preferences.motor?.targetSizeIncrease || 0, dwellTime: preferences.motor?.dwellTime || 500 }, audio: { enableAudio: preferences.audio?.enableAudio || false, enableCaptions: preferences.audio?.enableCaptions || false, volume: preferences.audio?.volume || 0.7, audioDescription: preferences.audio?.audioDescription || false } }, configuration: { adapters: config.adapters || {}, features: config.features || {} } }; if (includePersonalData && preferences.analytics) { profile.analytics = { usagePatterns: preferences.analytics.usagePatterns, adaptationHistory: preferences.analytics.adaptationHistory, performanceMetrics: preferences.analytics.performanceMetrics }; } return profile; } function generateJSExport(profile) { return `/** * NeuroAdapt Accessibility Profile * Generated on ${(/* @__PURE__ */ new Date()).toISOString()} */ export default ${JSON.stringify(profile, null, 2)}; export const accessibilityPreferences = ${JSON.stringify(profile.accessibility, null, 2)}; export const adapterConfiguration = ${JSON.stringify(profile.configuration, null, 2)}; `; } function generateYAMLExport(profile) { const yamlContent = Object.entries(profile).map(([key, value]) => `${key}: ${JSON.stringify(value, null, 2)}`).join("\n"); return `# NeuroAdapt Accessibility Profile # Generated on ${(/* @__PURE__ */ new Date()).toISOString()} ${yamlContent} `; } async function importProfile(profilePath, options = {}) { console.log(chalk.blue("šŸ“„ Importing NeuroAdapt Accessibility Profile\n")); let inputPath = profilePath; if (!inputPath) { const { selectedPath } = await inquirer.prompt([ { type: "input", name: "selectedPath", message: "Path to accessibility profile file:", validate: async (input) => { if (!input) return "Please provide a file path"; if (!await fs.pathExists(input)) return "File does not exist"; return true; } } ]); inputPath = selectedPath; } const spinner = ora("Loading profile...").start(); try { const projectRoot = process.cwd(); const preferencesPath = path__default.join(projectRoot, ".neuroadapt", "preferences.json"); const configPath = path__default.join(projectRoot, "neuroadapt.config.js"); if (!await fs.pathExists(inputPath)) { spinner.fail(`Profile file not found: ${inputPath}`); return; } spinner.text = "Parsing profile data..."; const ext = path__default.extname(inputPath).toLowerCase(); let profile; if (ext === ".json") { profile = await fs.readJson(inputPath); } else if (ext === ".js" || ext === ".mjs") { const profileModule = await import(path__default.resolve(inputPath)); profile = profileModule.default || profileModule; } else { throw new Error(`Unsupported file format: ${ext}. Supported formats: .json, .js, .mjs`); } validateProfileStructure(profile); spinner.text = "Checking existing configuration..."; const hasExistingPrefs = await fs.pathExists(preferencesPath); const hasExistingConfig = await fs.pathExists(configPath); let shouldProceed = true; let mergeMode = options.merge; let createBackup = options.backup; if ((hasExistingPrefs || hasExistingConfig) && !options.force) { spinner.stop(); const answers = await inquirer.prompt([ { type: "list", name: "action", message: "Existing accessibility configuration found. What would you like to do?", choices: [ { name: "Merge with existing settings", value: "merge" }, { name: "Replace existing settings", value: "replace" }, { name: "Cancel import", value: "cancel" } ] }, { type: "confirm", name: "backup", message: "Create backup of existing configuration?", default: true, when: (answers2) => answers2.action !== "cancel" } ]); if (answers.action === "cancel") { console.log(chalk.yellow("Import cancelled by user.")); return; } mergeMode = answers.action === "merge"; createBackup = answers.backup; shouldProceed = true; } if (!shouldProceed) return; const importSpinner = ora("Importing profile...").start(); if (createBackup && (hasExistingPrefs || hasExistingConfig)) { const backupDir = path__default.join(projectRoot, ".neuroadapt", "backups"); const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-"); await fs.ensureDir(backupDir); if (hasExistingPrefs) { await fs.copy(preferencesPath, path__default.join(backupDir, `preferences-${timestamp}.json`)); } if (hasExistingConfig) { await fs.copy(configPath, path__default.join(backupDir, `config-${timestamp}.js`)); } importSpinner.text = "Backup created, applying new settings..."; } await applyProfileSettings(profile, projectRoot, mergeMode, hasExistingPrefs, hasExistingConfig); importSpinner.succeed("Profile imported successfully!"); console.log(chalk.green("\nāœ… Import completed:")); console.log(chalk.gray(`šŸ“ Source: ${inputPath}`)); console.log(chalk.gray(`šŸ”„ Mode: ${mergeMode ? "Merged" : "Replaced"}`)); console.log(chalk.gray(`šŸ’¾ Backup: ${createBackup ? "Created" : "Skipped"}`)); console.log(chalk.blue("\nšŸ’” Next steps:")); console.log(chalk.gray("• Restart your application to apply new settings")); console.log(chalk.gray("• Verify accessibility features are working as expected")); console.log(chalk.gray("• Customize settings further if needed")); } catch (error) { spinner.fail("Failed to import profile"); console.error(chalk.red(error instanceof Error ? error.message : "Unknown error")); process.exit(1); } } function validateProfileStructure(profile) { if (!profile || typeof profile !== "object") { throw new Error("Invalid profile: must be an object"); } if (!profile.accessibility) { throw new Error("Invalid profile: missing accessibility configuration"); } const required = ["cognitive", "sensory", "motor", "audio"]; for (const section of required) { if (!profile.accessibility[section]) { throw new Error(`Invalid profile: missing accessibility.${section} configuration`); } } } async function applyProfileSettings(profile, projectRoot, mergeMode, hasExistingPrefs, hasExistingConfig) { const preferencesPath = path__default.join(projectRoot, ".neuroadapt", "preferences.json"); const configPath = path__default.join(projectRoot, "neuroadapt.config.js"); let preferences = profile.accessibility; if (mergeMode && hasExistingPrefs) { const existing = await fs.readJson(preferencesPath); preferences = mergeDeep(existing, preferences); } preferences.importedAt = (/* @__PURE__ */ new Date()).toISOString(); preferences.importedFrom = profile.name || "Unknown Profile"; preferences.version = profile.version || "1.1.0"; await fs.ensureDir(path__default.dirname(preferencesPath)); await fs.writeJson(preferencesPath, preferences, { spaces: 2 }); if (profile.configuration) { let config = profile.configuration; if (mergeMode && hasExistingConfig) { const existingModule = await import(path__default.resolve(configPath)); const existing = existingModule.default || existingModule; config = mergeDeep(existing, config); } const configContent = generateConfigFile(config); await fs.writeFile(configPath, configContent); } } function mergeDeep(target, source) { const result = { ...target }; for (const key in source) { if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) { result[key] = mergeDeep(result[key] || {}, source[key]); } else { result[key] = source[key]; } } return result; } function generateConfigFile(config) { return `/** * NeuroAdapt Configuration * Imported on ${(/* @__PURE__ */ new Date()).toISOString()} */ export default ${JSON.stringify(config, null, 2)}; `; } async function initProject(options = {}) { console.log(chalk.blue("šŸš€ Initializing NeuroAdapt SDK in existing project\n")); const spinner = ora("Analyzing project structure...").start(); try { const projectRoot = process.cwd(); const packageJsonPath = path__default.join(projectRoot, "package.json"); if (!await fs.pathExists(packageJsonPath)) { spinner.fail("No package.json found. Please run this command in a project directory."); return; } const packageJson = await fs.readJson(packageJsonPath); const isTypeScript = options.typescript ?? (await fs.pathExists(path__default.join(projectRoot, "tsconfig.json")) || packageJson.devDependencies?.typescript || packageJson.dependencies?.typescript); spinner.stop(); const answers = await inquirer.prompt([ { type: "input", name: "projectName", message: "Project name:", default: packageJson.name || path__default.basename(projectRoot) }, { type: "checkbox", name: "features", message: "Select accessibility features to enable:", choices: [ { name: "Cognitive Load Management", value: "cognitive", checked: true }, { name: "Sensory Adaptations (contrast, motion)", value: "sensory", checked: true }, { name: "Motor Accessibility (keyboard nav)", value: "motor", checked: true }, { name: "Audio Support (captions, descriptions)", value: "audio", checked: true }, { name: "AI-Powered Personalization", value: "ai", checked: false }, { name: "Quantum Computing Support", value: "quantum", checked: false }, { name: "VR/AR Safety Features", value: "vr", checked: false } ], when: !options.features }, { type: "list", name: "framework", message: "What framework are you using?", choices: [ { name: "React", value: "react" }, { name: "Vue.js", value: "vue" }, { name: "Angular", value: "angular" }, { name: "Svelte", value: "svelte" }, { name: "Vanilla JavaScript/TypeScript", value: "vanilla" }, { name: "Node.js (Backend)", value: "node" } ] }, { type: "confirm", name: "setupTesting", message: "Set up accessibility testing?", default: true } ]); const features = options.features || answers.features; const setupSpinner = ora("Setting up NeuroAdapt SDK...").start(); const dependencies = packageJson.dependencies || {}; const devDependencies = packageJson.devDependencies || {}; dependencies["@neuroadapt/core"] = "^1.1.0"; if (features.includes("ai")) { dependencies["@neuroadapt/ai"] = "^1.1.0"; } if (features.includes("quantum")) { dependencies["@neuroadapt/quantum"] = "^1.1.0"; } if (features.includes("vr")) { dependencies["@neuroadapt/vr"] = "^1.1.0"; } if (answers.framework === "react") { dependencies["react"] = dependencies["react"] || "^18.0.0"; dependencies["react-dom"] = dependencies["react-dom"] || "^18.0.0"; } if (answers.setupTesting