@every-env/cli
Version:
Multi-agent orchestrator for AI-powered development workflows
137 lines • 4.94 kB
JavaScript
import { existsSync, readFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { glob } from 'glob';
import { CommandPatternSchema } from './types.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
export class PatternRegistry {
patterns = new Map();
builtInPatternsPath;
namespace;
constructor(options = {}) {
this.builtInPatternsPath = options.builtInPatternsPath || join(__dirname, '../../../resources/patterns');
this.namespace = options.namespace;
}
async loadBuiltInPatterns(command) {
const searchPath = command
? join(this.builtInPatternsPath, command, '*.json')
: join(this.builtInPatternsPath, '**/*.json');
const files = await glob(searchPath, { absolute: true });
for (const file of files) {
try {
const content = readFileSync(file, 'utf-8');
const data = JSON.parse(content);
const patterns = Array.isArray(data) ? data : [data];
for (const pattern of patterns) {
const validated = CommandPatternSchema.parse(pattern);
const patternName = this.getPatternName(validated, command);
this.patterns.set(patternName, {
pattern: {
...validated,
builtIn: true,
command: command || this.extractCommandFromPath(file),
},
source: 'built-in',
filePath: file,
});
}
}
catch (error) {
console.error(`Failed to load built-in pattern from ${file}:`, error);
}
}
}
async loadUserPatterns(patterns) {
for (const pattern of patterns) {
try {
const validated = CommandPatternSchema.parse(pattern);
const patternName = this.getPatternName(validated);
this.patterns.set(patternName, {
pattern: {
...validated,
builtIn: false,
},
source: 'user',
});
}
catch (error) {
console.error(`Failed to load user pattern ${pattern.name}:`, error);
}
}
}
async loadProjectPatterns(configPath) {
if (!existsSync(configPath)) {
return;
}
try {
const content = readFileSync(configPath, 'utf-8');
const config = JSON.parse(content);
if (config.patterns) {
for (const pattern of config.patterns) {
const validated = CommandPatternSchema.parse(pattern);
const patternName = this.getPatternName(validated);
this.patterns.set(patternName, {
pattern: {
...validated,
builtIn: false,
},
source: 'project',
filePath: configPath,
});
}
}
}
catch (error) {
console.error(`Failed to load project patterns from ${configPath}:`, error);
}
}
get(name) {
const registered = this.patterns.get(name);
return registered?.pattern;
}
getAll() {
return Array.from(this.patterns.values()).map(r => r.pattern);
}
getByCommand(command) {
return Array.from(this.patterns.values())
.filter(r => r.pattern.command === command || r.pattern.namespace === command)
.map(r => r.pattern);
}
getByNamespace(namespace) {
return Array.from(this.patterns.values())
.filter(r => r.pattern.namespace === namespace)
.map(r => r.pattern);
}
has(name) {
return this.patterns.has(name);
}
getSource(name) {
return this.patterns.get(name)?.source;
}
getPatternName(pattern, defaultCommand) {
if (this.namespace) {
return `${this.namespace}.${pattern.name}`;
}
if (pattern.namespace) {
return `${pattern.namespace}.${pattern.name}`;
}
if (pattern.command) {
return `${pattern.command}.${pattern.name}`;
}
if (defaultCommand) {
return `${defaultCommand}.${pattern.name}`;
}
return pattern.name;
}
extractCommandFromPath(filePath) {
const match = filePath.match(/resources\/patterns\/([^/]+)\//);
return match ? match[1] : undefined;
}
clear() {
this.patterns.clear();
}
size() {
return this.patterns.size;
}
}
//# sourceMappingURL=pattern-registry.js.map