@ace-sdk/cli
Version:
ACE CLI - Command-line tool for intelligent pattern learning and playbook management
83 lines • 3.41 kB
JavaScript
/**
* Server Client - Wrapper for @ace-sdk/core AceClient
*
* Provides backwards-compatible ACEServerClient alias for CLI commands.
*
* @package @ace-sdk/cli
*/
import { AceClient, getXdgConfigPath, ensureConfigDirectory } from '@ace-sdk/core';
import { logger as globalLogger, globalOptions } from './logger.js';
/**
* ACEServerClient - Backwards-compatible alias for AceClient
*
* Accepts optional Logger for backwards compatibility with CLI commands
* that were passing a Logger instance as the second argument.
*
* Also includes CLI-specific methods like saveConfig that save to disk.
*
* @deprecated Use AceClient directly from @ace-sdk/core
*/
export class ACEServerClient extends AceClient {
constructor(config, loggerArg) {
const logger = loggerArg || globalLogger;
super(config, {
logger,
customHeaders: { 'X-ACE-Client': 'cli' },
onTokenExpiring: (secondsRemaining) => {
const hours = Math.floor(secondsRemaining / 3600);
if (secondsRemaining < 3600) {
// Urgent: < 1 hour
const minutes = Math.floor(secondsRemaining / 60);
logger.warn?.(`⚠️ Session expires in ${minutes} minutes! Run \`ace-cli login\` to refresh.`);
}
else {
// Warning: < 24 hours
logger.warn?.(`⏰ Session expires in ${hours} hours. Run \`ace-cli login\` to refresh.`);
}
}
});
}
/**
* Save ACE configuration to ~/.config/ace/config.json (XDG-compliant)
* CLI-specific method - not part of core AceClient
*
* v3.8.1: Preserves existing orgs section and other fields
* v2.1.1: Fixed to use XDG config path instead of legacy ~/.ace/
*/
async saveConfig(serverUrl, apiToken, projectId) {
const fs = await import('fs/promises');
// Use XDG-compliant config path
const configPath = getXdgConfigPath();
// Ensure directory exists with secure permissions
ensureConfigDirectory(configPath);
// v3.8.1: Read existing config to preserve orgs section and other fields
let existingConfig = {};
try {
const existingContent = await fs.readFile(configPath, 'utf8');
existingConfig = JSON.parse(existingContent);
}
catch {
// File doesn't exist or is invalid - start fresh
if (!globalOptions.json && !globalOptions.quiet) {
console.error('ℹ️ No existing config found, creating new one');
}
}
// Merge new values with existing config (preserves orgs section)
const config = {
...existingConfig, // Keep existing fields (including orgs)
serverUrl, // Update these fields
apiToken,
projectId
};
await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf8');
if (!globalOptions.json && !globalOptions.quiet) {
console.error(`✅ Configuration saved to ${configPath}`);
if (config.orgs) {
console.error(` Multi-org: ${Object.keys(config.orgs).length} organization(s) preserved`);
}
}
}
}
// Also export AceClient directly for new code
export { AceClient };
//# sourceMappingURL=server-client.js.map