import React, { useCallback, useEffect, useState } from 'react' import { Box, Text, useInput } from 'ink' import { Select } from '@inkjs/ui' import { getTheme } from '../utils/theme' import { ConfigureNpmPrefix } from './ConfigureNpmPrefix.tsx' import { platform } from 'process' import { checkNpmPermissions, getDefaultNpmPrefix, getPermissionsCommand, } from '../utils/autoUpdater.js' import { saveGlobalConfig, getGlobalConfig } from '../utils/config' import { logEvent } from '../services/statsig' import { PRODUCT_NAME } from '../constants/product' import { PressEnterToContinue } from '../components/PressEnterToContinue' type Props = { onDone: () => void doctorMode?: boolean } type Option = { label: string value: 'auto' | 'manual' | 'ignore' description: string } export function Doctor({ onDone, doctorMode = false }: Props): React.ReactNode { const [hasPermissions, setHasPermissions] = useState(null) const [npmPrefix, setNpmPrefix] = useState(null) const [selectedOption, setSelectedOption] = useState( null, ) const [customPrefix, setCustomPrefix] = useState( getDefaultNpmPrefix(), ) const theme = getTheme() const [showingPermissionsMessage, setShowingPermissionsMessage] = useState(false) const options: Option[] = [ { label: `Manually fix permissions on current npm prefix (Recommended)`, value: 'manual', description: platform === 'win32' ? 'Uses icacls to grant write permissions' : 'Uses sudo to change ownership', }, { label: 'Create new npm prefix directory', value: 'auto', description: 'Creates a new directory for global npm packages in your home directory', }, { label: 'Skip configuration until next session', value: 'ignore', description: 'Skip this warning (you will be reminded again later)', }, ] const checkPermissions = useCallback(async () => { const result = await checkNpmPermissions() logEvent('tengu_auto_updater_permissions_check', { hasPermissions: result.hasPermissions.toString(), npmPrefix: result.npmPrefix ?? 'null', }) setHasPermissions(result.hasPermissions) if (result.npmPrefix) { setNpmPrefix(result.npmPrefix) } if (result.hasPermissions) { const config = getGlobalConfig() saveGlobalConfig({ ...config, autoUpdaterStatus: 'enabled', }) if (!doctorMode) { onDone() } } }, [onDone, doctorMode]) useEffect(() => { logEvent('tengu_auto_updater_config_start', {}) checkPermissions() }, [checkPermissions]) useInput( (_input, key) => { if ( (showingPermissionsMessage || (doctorMode && hasPermissions === true)) && key.return ) { onDone() } }, { isActive: showingPermissionsMessage || (doctorMode && hasPermissions === true), }, ) if (hasPermissions === null) { return ( Checking npm permissions… ) } if (hasPermissions === true) { if (doctorMode) { return ( ✓ npm permissions: OK Your installation is healthy and ready for auto-updates. ) } return ( ✓ Auto-updates enabled ) } return ( Enable automatic updates? {PRODUCT_NAME} can't update itself because it doesn't have permissions. Do you want to fix this to get automatic updates? {!selectedOption && ( Select an option below to fix the permissions issue: