Skip to content

Commit

Permalink
feat: implement user preferences for analytics consent and installati…
Browse files Browse the repository at this point in the history
…on tracking

- Added functions to manage user preferences for analytics, including reading and writing preferences to a JSON file.
- Implemented a prompt to ask users for consent to share anonymous installation analytics.
- Integrated analytics tracking into the package installation process, allowing for tracking of installations based on user consent.
- Enhanced the overall user experience by providing options for analytics participation during package installation.

These changes improve user engagement and provide valuable insights into package usage.
  • Loading branch information
michaellatman committed Dec 4, 2024
1 parent 266062d commit 85583e6
Showing 1 changed file with 82 additions and 0 deletions.
82 changes: 82 additions & 0 deletions src/utils/package-management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,84 @@ import path from 'path';
import fs from 'fs';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import os from 'os';

declare function fetch(url: string, init?: any): Promise<{ ok: boolean; statusText: string }>;

const execAsync = promisify(exec);

interface MCPPreferences {
allowAnalytics?: boolean;
}

function getPreferencesPath(): string {
if (process.platform === 'win32') {
const appData = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');
return path.join(appData, 'mcp-get', 'preferences.json');
}

// Unix-like systems (Linux, macOS)
const homeDir = os.homedir();
return path.join(homeDir, '.mcp-get', 'preferences.json');
}

function readPreferences(): MCPPreferences {
const prefsPath = getPreferencesPath();
if (!fs.existsSync(prefsPath)) {
return {};
}
try {
return JSON.parse(fs.readFileSync(prefsPath, 'utf8'));
} catch (error) {
return {};
}
}

function writePreferences(prefs: MCPPreferences): void {
const prefsPath = getPreferencesPath();
const prefsDir = path.dirname(prefsPath);

if (!fs.existsSync(prefsDir)) {
fs.mkdirSync(prefsDir, { recursive: true });
}

fs.writeFileSync(prefsPath, JSON.stringify(prefs, null, 2));
}

async function checkAnalyticsConsent(): Promise<boolean> {
const prefs = readPreferences();

if (typeof prefs.allowAnalytics === 'boolean') {
return prefs.allowAnalytics;
}

const { allowAnalytics } = await inquirer.prompt<{ allowAnalytics: boolean }>([{
type: 'confirm',
name: 'allowAnalytics',
message: 'Would you like to help improve mcp-get by sharing anonymous installation analytics?',
default: true
}]);

writePreferences({ ...prefs, allowAnalytics });
return allowAnalytics;
}

async function trackInstallation(packageName: string): Promise<void> {
try {
const response = await fetch(`https://mcp-get.com/api/packages/${packageName}/install`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Failed to track installation: ${response.statusText}`);
}
} catch (error) {
console.warn('Failed to track package installation');
}
}

async function promptForEnvVars(packageName: string): Promise<Record<string, string> | undefined> {
const helpers = packageHelpers[packageName];
if (!helpers?.requiredEnvVars) {
Expand Down Expand Up @@ -171,6 +246,13 @@ export async function installPackage(pkg: Package): Promise<void> {

await installMCPServer(pkg.name, envVars, pkg.runtime);
console.log('Updated Claude desktop configuration');

// Check analytics consent and track if allowed
const analyticsAllowed = await checkAnalyticsConsent();
if (analyticsAllowed) {
await trackInstallation(pkg.name);
}

await promptForRestart();
} catch (error) {
console.error('Failed to install package:', error);
Expand Down

0 comments on commit 85583e6

Please sign in to comment.