shipdeck
Version:
Ship MVPs in 48 hours. Fix bugs in 30 seconds. The command deck for developers who ship.
170 lines (156 loc) • 4.34 kB
JavaScript
/**
* Agent Registry - Simple Map-based storage for agent instances
*
* Provides basic registration, retrieval, and management functionality
* for the ultimate template agent system.
*
* @author ShipDeck Team
* @version 1.0.0
*/
/**
* Agent Registry class that manages agent instances using a Map
*/
class AgentRegistry {
/**
* Create a new AgentRegistry instance
*/
constructor() {
/**
* Internal Map to store agent instances
* @private
* @type {Map<string, Object>}
*/
this._agents = new Map();
}
/**
* Register an agent instance with a given name
*
* @param {string} name - Unique identifier for the agent
* @param {Object} agent - Agent instance to register
* @throws {Error} If name is not a string or agent is not provided
* @throws {Error} If agent with the same name is already registered
* @example
* registry.register('backend-architect', new BackendArchitect());
*/
register(name, agent) {
if (typeof name !== 'string' || !name.trim()) {
throw new Error('Agent name must be a non-empty string');
}
if (!agent) {
throw new Error('Agent instance is required');
}
if (this._agents.has(name)) {
throw new Error(`Agent '${name}' is already registered`);
}
this._agents.set(name, agent);
}
/**
* Retrieve an agent instance by name
*
* @param {string} name - Name of the agent to retrieve
* @returns {Object|undefined} Agent instance or undefined if not found
* @example
* const architect = registry.get('backend-architect');
*/
get(name) {
if (typeof name !== 'string') {
return undefined;
}
return this._agents.get(name);
}
/**
* Check if an agent is registered
*
* @param {string} name - Name of the agent to check
* @returns {boolean} True if agent exists, false otherwise
* @example
* if (registry.has('frontend-developer')) {
* // Agent is available
* }
*/
has(name) {
if (typeof name !== 'string') {
return false;
}
return this._agents.has(name);
}
/**
* Get a list of all registered agent names
*
* @returns {string[]} Array of registered agent names
* @example
* const agentNames = registry.list();
* console.log('Available agents:', agentNames);
*/
list() {
return Array.from(this._agents.keys()).sort();
}
/**
* Get the number of registered agents
*
* @returns {number} Count of registered agents
* @example
* console.log(`${registry.size()} agents registered`);
*/
size() {
return this._agents.size;
}
/**
* Remove an agent from the registry
*
* @param {string} name - Name of the agent to remove
* @returns {boolean} True if agent was removed, false if not found
* @example
* if (registry.unregister('old-agent')) {
* console.log('Agent removed successfully');
* }
*/
unregister(name) {
if (typeof name !== 'string') {
return false;
}
return this._agents.delete(name);
}
/**
* Clear all registered agents (useful for testing)
*
* @example
* registry.clear(); // Remove all agents
*/
clear() {
this._agents.clear();
}
/**
* Get all agent entries as [name, agent] pairs
*
* @returns {Array<[string, Object]>} Array of [name, agent] tuples
* @example
* for (const [name, agent] of registry.entries()) {
* console.log(`Agent: ${name}`, agent);
* }
*/
entries() {
return Array.from(this._agents.entries());
}
}
/**
* Create and export a singleton instance of the AgentRegistry
* This ensures all parts of the application use the same registry
*
* @type {AgentRegistry}
*/
const agentRegistry = new AgentRegistry();
// Export both the class and the singleton instance
module.exports = {
AgentRegistry,
registry: agentRegistry,
// Convenience exports for direct access to singleton methods
register: agentRegistry.register.bind(agentRegistry),
get: agentRegistry.get.bind(agentRegistry),
has: agentRegistry.has.bind(agentRegistry),
list: agentRegistry.list.bind(agentRegistry),
size: agentRegistry.size.bind(agentRegistry),
unregister: agentRegistry.unregister.bind(agentRegistry),
clear: agentRegistry.clear.bind(agentRegistry),
entries: agentRegistry.entries.bind(agentRegistry)
};