UNPKG

termcode

Version:

Superior terminal AI coding agent with enterprise-grade security, intelligent error recovery, performance monitoring, and plugin system - Advanced Claude Code alternative

164 lines (163 loc) 5.35 kB
import { promises as fs } from "node:fs"; import path from "node:path"; import os from "node:os"; import { log } from "../util/logging.js"; const globalMacrosPath = path.join(os.homedir(), ".termcode", "macros.json"); const globalConfigPath = path.join(os.homedir(), ".termcode", "macro-config.json"); const defaultConfig = { maxConcurrentExecutions: 3, defaultTimeout: 300000, // 5 minutes enableRecording: true, autoSave: true }; // Ensure macro directory exists async function ensureMacroDir() { const dir = path.dirname(globalMacrosPath); await fs.mkdir(dir, { recursive: true }); } // Load global macros export async function loadGlobalMacros() { try { await ensureMacroDir(); const content = await fs.readFile(globalMacrosPath, "utf8"); return JSON.parse(content); } catch (error) { // Return empty storage if file doesn't exist return { macros: [], lastUpdated: new Date().toISOString() }; } } // Save global macros export async function saveGlobalMacros(storage) { try { await ensureMacroDir(); storage.lastUpdated = new Date().toISOString(); await fs.writeFile(globalMacrosPath, JSON.stringify(storage, null, 2), "utf8"); } catch (error) { log.error("Failed to save macros:", error); throw error; } } // Load project-specific macros export async function loadProjectMacros(projectPath) { try { const macroPath = path.join(projectPath, ".termcode-macros.json"); const content = await fs.readFile(macroPath, "utf8"); return JSON.parse(content); } catch (error) { return { macros: [], lastUpdated: new Date().toISOString() }; } } // Save project-specific macros export async function saveProjectMacros(projectPath, storage) { try { const macroPath = path.join(projectPath, ".termcode-macros.json"); storage.lastUpdated = new Date().toISOString(); await fs.writeFile(macroPath, JSON.stringify(storage, null, 2), "utf8"); } catch (error) { log.error("Failed to save project macros:", error); throw error; } } // Load all macros (global + project) export async function loadAllMacros(projectPath) { const globalStorage = await loadGlobalMacros(); let allMacros = [...globalStorage.macros]; if (projectPath) { const projectStorage = await loadProjectMacros(projectPath); allMacros.push(...projectStorage.macros); } return allMacros; } // Add macro export async function addMacro(macro, projectPath) { if (macro.scope === "global" || !projectPath) { const storage = await loadGlobalMacros(); // Check for existing macro with same name const existingIndex = storage.macros.findIndex(m => m.name === macro.name); if (existingIndex >= 0) { storage.macros[existingIndex] = macro; } else { storage.macros.push(macro); } await saveGlobalMacros(storage); } else { const storage = await loadProjectMacros(projectPath); const existingIndex = storage.macros.findIndex(m => m.name === macro.name); if (existingIndex >= 0) { storage.macros[existingIndex] = macro; } else { storage.macros.push(macro); } await saveProjectMacros(projectPath, storage); } } // Remove macro export async function removeMacro(name, projectPath) { // Try global first const globalStorage = await loadGlobalMacros(); const globalIndex = globalStorage.macros.findIndex(m => m.name === name); if (globalIndex >= 0) { globalStorage.macros.splice(globalIndex, 1); await saveGlobalMacros(globalStorage); return true; } // Try project if path provided if (projectPath) { const projectStorage = await loadProjectMacros(projectPath); const projectIndex = projectStorage.macros.findIndex(m => m.name === name); if (projectIndex >= 0) { projectStorage.macros.splice(projectIndex, 1); await saveProjectMacros(projectPath, projectStorage); return true; } } return false; } // Get macro by name export async function getMacro(name, projectPath) { const allMacros = await loadAllMacros(projectPath); return allMacros.find(m => m.name === name) || null; } // Update macro usage count export async function incrementMacroUsage(name, projectPath) { const macro = await getMacro(name, projectPath); if (macro) { macro.usageCount++; macro.updatedAt = new Date().toISOString(); await addMacro(macro, projectPath); } } // Load macro config export async function loadMacroConfig() { try { await ensureMacroDir(); const content = await fs.readFile(globalConfigPath, "utf8"); return { ...defaultConfig, ...JSON.parse(content) }; } catch (error) { return defaultConfig; } } // Save macro config export async function saveMacroConfig(config) { try { await ensureMacroDir(); await fs.writeFile(globalConfigPath, JSON.stringify(config, null, 2), "utf8"); } catch (error) { log.error("Failed to save macro config:", error); } }