@nakedved/ano
Version:
Claude Code plugin for collaborative annotation and review
152 lines (151 loc) • 3.94 kB
JavaScript
/**
* Configuration Management
*
* Handles user identity and settings.
* Uses git config for identity - no login required.
*/
import { execSync } from 'node:child_process';
import { readFile, writeFile, access } from 'node:fs/promises';
import { homedir } from 'node:os';
import { join } from 'node:path';
// ============================================
// Git Identity
// ============================================
/**
* Get user identity from git config.
* Falls back to system username if git not configured.
*/
export function getGitIdentity() {
try {
const name = execSync('git config user.name', { encoding: 'utf-8' }).trim();
const email = execSync('git config user.email', { encoding: 'utf-8' }).trim();
if (name && email) {
return { name, email };
}
}
catch {
// Git not available or not configured
}
// Fallback to system username
const username = process.env.USER || process.env.USERNAME || 'anonymous';
return {
name: username,
email: `${username}@localhost`,
};
}
// ============================================
// Config File Management
// ============================================
const CONFIG_FILENAME = '.anorc.json';
/**
* Get the path to the global config file.
*/
function getGlobalConfigPath() {
return join(homedir(), CONFIG_FILENAME);
}
/**
* Get the path to the local (project) config file.
*/
function getLocalConfigPath() {
return join(process.cwd(), CONFIG_FILENAME);
}
/**
* Check if a config file exists at the given path.
*/
async function configExists(path) {
try {
await access(path);
return true;
}
catch {
return false;
}
}
/**
* Read a config file.
*/
async function readConfigFile(path) {
try {
const content = await readFile(path, 'utf-8');
return JSON.parse(content);
}
catch {
return null;
}
}
/**
* Write a config file.
*/
async function writeConfigFile(path, config) {
const content = JSON.stringify(config, null, 2);
await writeFile(path, content, 'utf-8');
}
// ============================================
// Public API
// ============================================
/**
* Get the current configuration.
* Priority: local config > global config > git identity
*/
export async function getConfig() {
// Try local config first
const localPath = getLocalConfigPath();
if (await configExists(localPath)) {
const local = await readConfigFile(localPath);
if (local)
return local;
}
// Try global config
const globalPath = getGlobalConfigPath();
if (await configExists(globalPath)) {
const global = await readConfigFile(globalPath);
if (global)
return global;
}
// Fall back to git identity
return {
user: getGitIdentity(),
};
}
/**
* Get just the user identity (convenience function).
*/
export async function getUser() {
const config = await getConfig();
return config.user;
}
/**
* Get the author string for annotations.
* Format: "Name <email>"
*/
export async function getAuthorString() {
const user = await getUser();
return `${user.name} <${user.email}>`;
}
/**
* Save configuration to the global config file.
*/
export async function saveGlobalConfig(config) {
await writeConfigFile(getGlobalConfigPath(), config);
}
/**
* Save configuration to the local (project) config file.
*/
export async function saveLocalConfig(config) {
await writeConfigFile(getLocalConfigPath(), config);
}
/**
* Initialize config from git identity.
* Optionally set a title.
*/
export async function initConfigFromGit(title, saveGlobally = true) {
const user = getGitIdentity();
if (title) {
user.title = title;
}
const config = { user };
if (saveGlobally) {
await saveGlobalConfig(config);
}
return config;
}