alnilam-cli
Version:
Git-native AI career coach that converts multi-year ambitions into weekly execution
235 lines (234 loc) ⢠8.93 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeGlobalConfig = writeGlobalConfig;
exports.setGlobalConfigValue = setGlobalConfigValue;
exports.getConfig = getConfig;
exports.getConfigWithDebug = getConfigWithDebug;
exports.resetConfig = resetConfig;
exports.displayConfigStatus = displayConfigStatus;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
// Removed automatic dotenv loading - users should set environment variables or use global config
// Global configuration paths
const GLOBAL_CONFIG_DIR = path.join(os.homedir(), '.config', 'alnilam');
const GLOBAL_CONFIG_FILE = path.join(GLOBAL_CONFIG_DIR, 'config.json');
// Default development configuration
const DEFAULT_CONFIG = {
supabaseUrl: 'http://127.0.0.1:54321',
supabaseAnonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0',
testEmail: 'test@example.com',
environment: 'development'
};
// Global configuration instance
let configInstance = null;
let configMetadata = {
globalConfigLoaded: false,
envVarsUsed: false
};
/**
* Ensure global config directory exists
*/
function ensureGlobalConfigDir() {
if (!fs.existsSync(GLOBAL_CONFIG_DIR)) {
fs.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
}
}
/**
* Read global configuration from ~/.config/alnilam/config.json
*/
function readGlobalConfig() {
try {
if (!fs.existsSync(GLOBAL_CONFIG_FILE)) {
return {};
}
const content = fs.readFileSync(GLOBAL_CONFIG_FILE, 'utf8');
return JSON.parse(content);
}
catch (error) {
return {};
}
}
/**
* Write global configuration to ~/.config/alnilam/config.json
*/
function writeGlobalConfig(config) {
ensureGlobalConfigDir();
fs.writeFileSync(GLOBAL_CONFIG_FILE, JSON.stringify(config, null, 2));
fs.chmodSync(GLOBAL_CONFIG_FILE, 0o600); // Secure file permissions
}
/**
* Update a single global configuration value
*/
function setGlobalConfigValue(key, value) {
const globalConfig = readGlobalConfig();
globalConfig[key] = value;
writeGlobalConfig(globalConfig);
// Reset config instance to reload with new values
configInstance = null;
}
/**
* Load environment configuration with safe precedence
* Configuration precedence (highest to lowest):
* 1. Environment variables (SUPABASE_URL, SUPABASE_ANON_KEY, TEST_EMAIL)
* 2. Global configuration (~/.config/alnilam/config.json)
* 3. Defaults (development settings)
*/
function loadEnvironmentConfig() {
// Load global configuration
const globalConfig = readGlobalConfig();
if (Object.keys(globalConfig).length > 0) {
configMetadata.globalConfigLoaded = true;
}
// Check if environment variables are being used
if (process.env.SUPABASE_URL || process.env.SUPABASE_ANON_KEY || process.env.TEST_EMAIL) {
configMetadata.envVarsUsed = true;
}
// Get configuration with precedence: env vars > global config > defaults
const supabaseUrl = process.env.SUPABASE_URL || globalConfig.supabaseUrl || DEFAULT_CONFIG.supabaseUrl;
const supabaseAnonKey = process.env.SUPABASE_ANON_KEY || globalConfig.supabaseAnonKey || DEFAULT_CONFIG.supabaseAnonKey;
const testEmail = process.env.TEST_EMAIL || globalConfig.testEmail || DEFAULT_CONFIG.testEmail;
// Detect environment based on URL pattern
let environment = 'auto';
if (supabaseUrl.includes('supabase.co')) {
environment = 'production';
}
else if (supabaseUrl.includes('127.0.0.1') || supabaseUrl.includes('localhost')) {
environment = 'development';
}
return {
supabaseUrl,
supabaseAnonKey,
testEmail,
environment
};
}
/**
* Validate configuration and provide helpful error messages
*/
function validateConfig(config) {
const errors = [];
// Validate Supabase URL format
if (!config.supabaseUrl.startsWith('http://') && !config.supabaseUrl.startsWith('https://')) {
errors.push('SUPABASE_URL must be a valid HTTP/HTTPS URL');
}
// Validate Supabase key format (should be a JWT)
if (!config.supabaseAnonKey.startsWith('eyJ')) {
errors.push('SUPABASE_ANON_KEY appears to be invalid (should be a JWT token starting with "eyJ")');
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(config.testEmail)) {
errors.push('TEST_EMAIL must be a valid email address');
}
if (errors.length > 0) {
console.error('ā Configuration Error:');
errors.forEach(error => console.error(` ⢠${error}`));
console.error('\nš” Troubleshooting:');
console.error(' ⢠Set environment variables: export SUPABASE_URL=... SUPABASE_ANON_KEY=...');
console.error(' ⢠Or use global config: alnl config set supabase-url <url>');
console.error(' ⢠Check configuration status: alnl config status');
process.exit(1);
}
}
/**
* Get the global configuration instance
*/
function getConfig() {
if (!configInstance) {
configInstance = loadEnvironmentConfig();
validateConfig(configInstance);
}
return configInstance;
}
/**
* Get configuration with environment info for debugging
*/
function getConfigWithDebug() {
const config = getConfig();
return {
...config,
envVarsUsed: configMetadata.envVarsUsed,
globalConfigLoaded: configMetadata.globalConfigLoaded,
globalConfigFile: GLOBAL_CONFIG_FILE,
isProduction: config.environment === 'production'
};
}
/**
* Reset configuration (useful for testing)
*/
function resetConfig() {
configInstance = null;
}
/**
* Display configuration status
*/
function displayConfigStatus() {
const config = getConfigWithDebug();
console.log('š§ Alnilam Configuration Status');
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
console.log(`Environment: ${config.environment === 'auto' ? 'auto-detected' : config.environment}`);
console.log(`Supabase URL: ${config.supabaseUrl}`);
console.log(`Environment Type: ${config.isProduction ? 'Production' : 'Development'}`);
// Show configuration sources in priority order
const sources = [];
if (config.envVarsUsed) {
sources.push('Environment variables');
}
if (config.globalConfigLoaded) {
sources.push('Global config: ~/.config/alnilam/config.json');
}
if (sources.length === 0) {
sources.push('Defaults (development)');
}
console.log(`Config Sources: ${sources.join(', ')}`);
if (config.environment === 'production') {
console.log('ā
Production configuration detected');
}
else if (config.environment === 'development') {
console.log('š ļø Development configuration detected');
}
else {
console.log('ā ļø Auto-detected configuration');
}
// Show setup guidance if no persistent config
if (!config.globalConfigLoaded && !config.envVarsUsed) {
console.log('\nš” Quick Setup:');
console.log(' ⢠Set global config: alnl config set supabase-url <your-url>');
console.log(' ⢠Set global key: alnl config set supabase-key <your-key>');
console.log(' ⢠Or set environment variables: export SUPABASE_URL=... SUPABASE_ANON_KEY=...');
}
}