diragent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1621 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/client/index.d.ts +63 -0
- package/dist/client/index.js +145 -0
- package/dist/client/index.js.map +1 -0
- package/dist/index.d.ts +256 -0
- package/dist/index.js +879 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.js +861 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +90 -0
- package/scripts/install.sh +67 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/index.ts","../../src/server/config.ts","../../src/server/db/index.ts","../../src/server/agents/manager.ts","../../src/server/api/routes.ts","../../src/server/ws/index.ts"],"sourcesContent":["import Fastify from 'fastify';\nimport fastifyWebsocket from '@fastify/websocket';\nimport fastifyCors from '@fastify/cors';\nimport fastifyStatic from '@fastify/static';\nimport pino from 'pino';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';\n\nimport { loadConfig, DirigentConfig } from './config.js';\nimport { initDatabase, getDatabase } from './db/index.js';\nimport { AgentManager } from './agents/manager.js';\nimport { registerApiRoutes } from './api/routes.js';\nimport { registerWebSocket } from './ws/index.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface ServerOptions {\n port: number;\n configPath: string;\n dataDir: string;\n}\n\nlet server: ReturnType<typeof Fastify> | null = null;\nlet agentManager: AgentManager | null = null;\nconst startTime = Date.now();\n\nexport async function startServer(options: ServerOptions) {\n const config = loadConfig(options.configPath);\n\n // Setup logging\n const logPath = join(options.dataDir, 'logs', 'dirigent.log');\n mkdirSync(dirname(logPath), { recursive: true });\n\n const logger = pino({\n level: config.logging?.level || 'info',\n transport: {\n targets: [\n {\n target: 'pino-pretty',\n options: { colorize: true },\n level: 'info',\n },\n {\n target: 'pino/file',\n options: { destination: logPath },\n level: 'debug',\n },\n ],\n },\n });\n\n // Initialize database\n const dbPath = join(options.dataDir, 'data', 'dirigent.db');\n mkdirSync(dirname(dbPath), { recursive: true });\n initDatabase(dbPath);\n\n // Create Fastify server\n server = Fastify({ logger });\n\n // Register plugins\n await server.register(fastifyCors, {\n origin: true,\n credentials: true,\n });\n\n await server.register(fastifyWebsocket);\n\n // Serve dashboard static files\n const dashboardPath = join(__dirname, '..', 'dashboard', 'dist');\n if (existsSync(dashboardPath)) {\n await server.register(fastifyStatic, {\n root: dashboardPath,\n prefix: '/',\n });\n }\n\n // Initialize agent manager\n agentManager = new AgentManager({\n dataDir: options.dataDir,\n config,\n logger,\n });\n\n // Register API routes\n registerApiRoutes(server, {\n config,\n agentManager,\n startTime,\n });\n\n // Register WebSocket handlers\n registerWebSocket(server, {\n config,\n agentManager,\n });\n\n // Health check\n server.get('/health', async () => ({ status: 'ok', uptime: Math.floor((Date.now() - startTime) / 1000) }));\n\n // Graceful shutdown\n const shutdown = async (signal: string) => {\n logger.info(`Received ${signal}, shutting down...`);\n\n // Stop all agents\n if (agentManager) {\n await agentManager.stopAll();\n }\n\n // Close server\n if (server) {\n await server.close();\n }\n\n // Close database\n const db = getDatabase();\n if (db) db.close();\n\n process.exit(0);\n };\n\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('SIGINT', () => shutdown('SIGINT'));\n\n // Start server\n try {\n await server.listen({ port: options.port, host: config.server?.host || '0.0.0.0' });\n\n console.log(`\n╔══════════════════════════════════════════════════════════╗\n║ ║\n║ 🎭 DIRIGENT SERVER RUNNING ║\n║ ║\n║ Dashboard: http://localhost:${options.port.toString().padEnd(25)}║\n║ API: http://localhost:${options.port}/api${' '.repeat(21)}║\n║ WebSocket: ws://localhost:${options.port}/ws${' '.repeat(22)}║\n║ ║\n╚══════════════════════════════════════════════════════════╝\n`);\n } catch (err) {\n logger.error(err);\n process.exit(1);\n }\n}\n\n// Export for direct invocation\nif (process.env.DIRIGENT_CONFIG) {\n startServer({\n port: parseInt(process.env.DIRIGENT_PORT || '3000'),\n configPath: process.env.DIRIGENT_CONFIG,\n dataDir: process.env.DIRIGENT_DATA_DIR || '.dirigent',\n });\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\n\nconst AgentTemplateSchema = z.object({\n driver: z.string(),\n model: z.string().optional(),\n maxTokens: z.number().optional(),\n command: z.array(z.string()).optional(),\n env: z.record(z.string()).optional(),\n});\n\nconst ConfigSchema = z.object({\n version: z.string().default('1'),\n server: z\n .object({\n port: z.number().default(3000),\n host: z.string().default('0.0.0.0'),\n })\n .default({}),\n auth: z\n .object({\n enabled: z.boolean().default(true),\n adminToken: z.string().optional(),\n apiKeys: z.array(z.string()).optional(),\n })\n .default({}),\n agents: z\n .object({\n maxConcurrent: z.number().default(10),\n defaultTimeout: z.number().default(3600),\n templates: z.record(AgentTemplateSchema).default({}),\n })\n .default({}),\n logging: z\n .object({\n level: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n format: z.enum(['pretty', 'json']).default('pretty'),\n file: z.string().optional(),\n })\n .default({}),\n database: z\n .object({\n path: z.string().default('data/dirigent.db'),\n })\n .default({}),\n});\n\nexport type DirigentConfig = z.infer<typeof ConfigSchema>;\nexport type AgentTemplate = z.infer<typeof AgentTemplateSchema>;\n\nlet cachedConfig: DirigentConfig | null = null;\n\nexport function loadConfig(configPath?: string): DirigentConfig {\n if (cachedConfig) return cachedConfig;\n\n const path = configPath || findConfigPath();\n\n if (!path || !existsSync(path)) {\n // Return defaults\n cachedConfig = ConfigSchema.parse({});\n return cachedConfig;\n }\n\n const raw = readFileSync(path, 'utf-8');\n const parsed = JSON.parse(raw);\n cachedConfig = ConfigSchema.parse(parsed);\n\n return cachedConfig;\n}\n\nfunction findConfigPath(): string | null {\n const candidates = [\n join(process.cwd(), '.dirigent', 'config.json'),\n join(process.cwd(), 'dirigent.json'),\n join(process.env.HOME || '', '.dirigent', 'config.json'),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n\n return null;\n}\n\nexport function validateAuth(token: string, config: DirigentConfig): boolean {\n if (!config.auth.enabled) return true;\n\n // Check admin token\n if (config.auth.adminToken && token === config.auth.adminToken) return true;\n\n // Check API keys\n if (config.auth.apiKeys?.includes(token)) return true;\n\n return false;\n}\n","import Database from 'better-sqlite3';\n\nlet db: Database.Database | null = null;\n\nexport function initDatabase(path: string): Database.Database {\n db = new Database(path);\n\n // Enable WAL mode for better concurrency\n db.pragma('journal_mode = WAL');\n\n // Create tables\n db.exec(`\n -- Agents table\n CREATE TABLE IF NOT EXISTS agents (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n template TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'created',\n workspace TEXT,\n model TEXT,\n config TEXT,\n pid INTEGER,\n created_at INTEGER NOT NULL DEFAULT (unixepoch()),\n started_at INTEGER,\n stopped_at INTEGER,\n error TEXT\n );\n\n -- Agent logs table\n CREATE TABLE IF NOT EXISTS agent_logs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n agent_id TEXT NOT NULL,\n level TEXT NOT NULL,\n message TEXT NOT NULL,\n timestamp INTEGER NOT NULL DEFAULT (unixepoch() * 1000),\n metadata TEXT,\n FOREIGN KEY (agent_id) REFERENCES agents(id)\n );\n\n -- Tasks table\n CREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n agent_id TEXT,\n content TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n result TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch()),\n started_at INTEGER,\n completed_at INTEGER,\n error TEXT,\n FOREIGN KEY (agent_id) REFERENCES agents(id)\n );\n\n -- Audit log table\n CREATE TABLE IF NOT EXISTS audit_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action TEXT NOT NULL,\n actor TEXT,\n target_type TEXT,\n target_id TEXT,\n details TEXT,\n timestamp INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n -- Sessions table (for WebSocket connections)\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n user_id TEXT,\n connected_at INTEGER NOT NULL DEFAULT (unixepoch()),\n last_activity INTEGER NOT NULL DEFAULT (unixepoch()),\n metadata TEXT\n );\n\n -- Indexes\n CREATE INDEX IF NOT EXISTS idx_agent_logs_agent_id ON agent_logs(agent_id);\n CREATE INDEX IF NOT EXISTS idx_agent_logs_timestamp ON agent_logs(timestamp);\n CREATE INDEX IF NOT EXISTS idx_tasks_agent_id ON tasks(agent_id);\n CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);\n CREATE INDEX IF NOT EXISTS idx_audit_log_timestamp ON audit_log(timestamp);\n `);\n\n return db;\n}\n\nexport function getDatabase(): Database.Database | null {\n return db;\n}\n\n// Helper functions\nexport function insertAgent(agent: {\n id: string;\n name: string;\n template: string;\n workspace?: string;\n model?: string;\n config?: object;\n}) {\n const stmt = db!.prepare(`\n INSERT INTO agents (id, name, template, workspace, model, config)\n VALUES (?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n agent.id,\n agent.name,\n agent.template,\n agent.workspace || null,\n agent.model || null,\n agent.config ? JSON.stringify(agent.config) : null\n );\n}\n\nexport function updateAgent(id: string, updates: Record<string, any>) {\n const keys = Object.keys(updates);\n const values = keys.map((k) => (typeof updates[k] === 'object' ? JSON.stringify(updates[k]) : updates[k]));\n\n const stmt = db!.prepare(`\n UPDATE agents SET ${keys.map((k) => `${k} = ?`).join(', ')}\n WHERE id = ?\n `);\n\n stmt.run(...values, id);\n}\n\nexport function getAgent(id: string) {\n const stmt = db!.prepare('SELECT * FROM agents WHERE id = ?');\n const row = stmt.get(id) as any;\n if (row?.config) row.config = JSON.parse(row.config);\n return row;\n}\n\nexport function getAgents(includesStopped = false) {\n const stmt = db!.prepare(\n includesStopped\n ? 'SELECT * FROM agents ORDER BY created_at DESC'\n : \"SELECT * FROM agents WHERE status != 'stopped' ORDER BY created_at DESC\"\n );\n return stmt.all().map((row: any) => {\n if (row.config) row.config = JSON.parse(row.config);\n return row;\n });\n}\n\nexport function insertLog(log: {\n agentId: string;\n level: string;\n message: string;\n metadata?: object;\n}) {\n const stmt = db!.prepare(`\n INSERT INTO agent_logs (agent_id, level, message, metadata)\n VALUES (?, ?, ?, ?)\n `);\n\n stmt.run(log.agentId, log.level, log.message, log.metadata ? JSON.stringify(log.metadata) : null);\n}\n\nexport function getLogs(agentId: string, limit = 100) {\n const stmt = db!.prepare(`\n SELECT * FROM agent_logs\n WHERE agent_id = ?\n ORDER BY timestamp DESC\n LIMIT ?\n `);\n\n return stmt.all(agentId, limit).reverse().map((row: any) => {\n if (row.metadata) row.metadata = JSON.parse(row.metadata);\n return row;\n });\n}\n\nexport function audit(action: string, actor: string | null, targetType: string | null, targetId: string | null, details?: object) {\n const stmt = db!.prepare(`\n INSERT INTO audit_log (action, actor, target_type, target_id, details)\n VALUES (?, ?, ?, ?, ?)\n `);\n\n stmt.run(action, actor, targetType, targetId, details ? JSON.stringify(details) : null);\n}\n","import { EventEmitter } from 'events';\nimport { nanoid } from 'nanoid';\nimport { spawn, ChildProcess } from 'child_process';\nimport treeKill from 'tree-kill';\nimport { join } from 'path';\nimport { mkdirSync, existsSync } from 'fs';\nimport type { Logger } from 'pino';\n\nimport { DirigentConfig, AgentTemplate } from '../config.js';\nimport { insertAgent, updateAgent, getAgent, getAgents, insertLog, getLogs, audit } from '../db/index.js';\n\nexport interface Agent {\n id: string;\n name: string;\n template: string;\n status: 'created' | 'starting' | 'running' | 'idle' | 'stopping' | 'stopped' | 'error';\n workspace?: string;\n model?: string;\n pid?: number;\n process?: ChildProcess;\n currentTask?: string;\n createdAt: number;\n startedAt?: number;\n stoppedAt?: number;\n error?: string;\n}\n\ninterface ManagerOptions {\n dataDir: string;\n config: DirigentConfig;\n logger: Logger;\n}\n\nexport class AgentManager extends EventEmitter {\n private agents: Map<string, Agent> = new Map();\n private processes: Map<string, ChildProcess> = new Map();\n private dataDir: string;\n private config: DirigentConfig;\n private logger: Logger;\n\n constructor(options: ManagerOptions) {\n super();\n this.dataDir = options.dataDir;\n this.config = options.config;\n this.logger = options.logger;\n\n // Load existing agents from database\n this.loadAgents();\n }\n\n private loadAgents() {\n const dbAgents = getAgents(false);\n for (const dbAgent of dbAgents) {\n // Only load non-running agents; running agents will need to be respawned\n if (dbAgent.status !== 'stopped') {\n this.agents.set(dbAgent.id, {\n id: dbAgent.id,\n name: dbAgent.name,\n template: dbAgent.template,\n status: 'stopped', // Reset to stopped since we restarted\n workspace: dbAgent.workspace,\n model: dbAgent.model,\n createdAt: dbAgent.created_at * 1000,\n });\n\n // Update database\n updateAgent(dbAgent.id, { status: 'stopped' });\n }\n }\n }\n\n async spawn(options: {\n template: string;\n name?: string;\n workspace?: string;\n task?: string;\n model?: string;\n }): Promise<Agent> {\n const { template, name, workspace, task, model } = options;\n\n // Get template config\n const templateConfig = this.config.agents.templates[template];\n if (!templateConfig) {\n throw new Error(`Unknown template: ${template}`);\n }\n\n // Check max concurrent\n const runningCount = Array.from(this.agents.values()).filter(\n (a) => a.status === 'running' || a.status === 'starting'\n ).length;\n\n if (runningCount >= this.config.agents.maxConcurrent) {\n throw new Error(`Max concurrent agents (${this.config.agents.maxConcurrent}) reached`);\n }\n\n // Create agent\n const id = nanoid(12);\n const agentName = name || `${template}-${id.slice(0, 6)}`;\n const agentWorkspace = workspace || join(this.dataDir, 'workspaces', id);\n\n // Ensure workspace exists\n if (!existsSync(agentWorkspace)) {\n mkdirSync(agentWorkspace, { recursive: true });\n }\n\n const agent: Agent = {\n id,\n name: agentName,\n template,\n status: 'created',\n workspace: agentWorkspace,\n model: model || templateConfig.model,\n currentTask: task,\n createdAt: Date.now(),\n };\n\n // Save to database\n insertAgent({\n id: agent.id,\n name: agent.name,\n template: agent.template,\n workspace: agent.workspace,\n model: agent.model,\n });\n\n audit('agent.created', null, 'agent', id, { name: agentName, template });\n\n this.agents.set(id, agent);\n this.emit('agent:created', agent);\n\n // Start the agent process\n await this.startAgent(agent, templateConfig, task);\n\n return agent;\n }\n\n private async startAgent(agent: Agent, template: AgentTemplate, initialTask?: string) {\n agent.status = 'starting';\n updateAgent(agent.id, { status: 'starting' });\n this.emit('agent:starting', agent);\n\n try {\n const { command, env } = this.buildCommand(agent, template);\n\n this.logger.info({ agentId: agent.id, command }, 'Starting agent');\n\n const proc = spawn(command[0], command.slice(1), {\n cwd: agent.workspace,\n env: {\n ...process.env,\n ...env,\n DIRIGENT_AGENT_ID: agent.id,\n DIRIGENT_AGENT_NAME: agent.name,\n },\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n agent.pid = proc.pid;\n agent.process = proc;\n agent.status = 'running';\n agent.startedAt = Date.now();\n\n updateAgent(agent.id, {\n status: 'running',\n pid: proc.pid,\n started_at: Math.floor(Date.now() / 1000),\n });\n\n this.processes.set(agent.id, proc);\n\n // Handle stdout\n proc.stdout?.on('data', (data) => {\n const message = data.toString().trim();\n if (message) {\n this.log(agent.id, 'info', message);\n }\n });\n\n // Handle stderr\n proc.stderr?.on('data', (data) => {\n const message = data.toString().trim();\n if (message) {\n this.log(agent.id, 'error', message);\n }\n });\n\n // Handle exit\n proc.on('exit', (code, signal) => {\n this.logger.info({ agentId: agent.id, code, signal }, 'Agent exited');\n\n agent.status = code === 0 ? 'stopped' : 'error';\n agent.stoppedAt = Date.now();\n if (code !== 0) {\n agent.error = `Exited with code ${code}`;\n }\n\n updateAgent(agent.id, {\n status: agent.status,\n stopped_at: Math.floor(Date.now() / 1000),\n error: agent.error || null,\n });\n\n this.processes.delete(agent.id);\n this.emit('agent:stopped', agent);\n\n audit('agent.stopped', null, 'agent', agent.id, { code, signal });\n });\n\n proc.on('error', (err) => {\n this.logger.error({ agentId: agent.id, err }, 'Agent process error');\n agent.status = 'error';\n agent.error = err.message;\n\n updateAgent(agent.id, { status: 'error', error: err.message });\n this.emit('agent:error', agent, err);\n });\n\n this.emit('agent:running', agent);\n audit('agent.started', null, 'agent', agent.id, { pid: proc.pid });\n\n // Send initial task if provided\n if (initialTask && proc.stdin) {\n proc.stdin.write(initialTask + '\\n');\n }\n } catch (err: any) {\n agent.status = 'error';\n agent.error = err.message;\n updateAgent(agent.id, { status: 'error', error: err.message });\n this.emit('agent:error', agent, err);\n throw err;\n }\n }\n\n private buildCommand(agent: Agent, template: AgentTemplate): { command: string[]; env: Record<string, string> } {\n const env: Record<string, string> = { ...template.env };\n\n switch (template.driver) {\n case 'claude-code':\n return {\n command: ['claude', '--dangerously-skip-permissions'],\n env: {\n ...env,\n ANTHROPIC_MODEL: agent.model || template.model || 'claude-sonnet-4-5',\n },\n };\n\n case 'codex':\n return {\n command: ['codex', '--model', agent.model || template.model || 'codex-1'],\n env,\n };\n\n case 'clawdbot':\n return {\n command: ['clawdbot', 'agent', '--headless'],\n env: {\n ...env,\n CLAWDBOT_MODEL: agent.model || template.model || 'claude-sonnet-4-5',\n },\n };\n\n case 'subprocess':\n if (!template.command || template.command.length === 0) {\n throw new Error('subprocess driver requires command');\n }\n return { command: template.command, env };\n\n default:\n throw new Error(`Unknown driver: ${template.driver}`);\n }\n }\n\n async stop(id: string, force = false): Promise<void> {\n const agent = this.agents.get(id);\n if (!agent) {\n throw new Error(`Agent not found: ${id}`);\n }\n\n if (agent.status !== 'running' && agent.status !== 'starting') {\n return;\n }\n\n agent.status = 'stopping';\n this.emit('agent:stopping', agent);\n\n const proc = this.processes.get(id);\n if (proc && proc.pid) {\n await new Promise<void>((resolve, reject) => {\n treeKill(proc.pid!, force ? 'SIGKILL' : 'SIGTERM', (err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n }\n\n audit('agent.stop_requested', null, 'agent', id, { force });\n }\n\n async stopAll(): Promise<void> {\n const promises = Array.from(this.agents.values())\n .filter((a) => a.status === 'running' || a.status === 'starting')\n .map((a) => this.stop(a.id, true));\n\n await Promise.allSettled(promises);\n }\n\n async send(id: string, message: string): Promise<void> {\n const agent = this.agents.get(id);\n if (!agent) {\n throw new Error(`Agent not found: ${id}`);\n }\n\n if (agent.status !== 'running') {\n throw new Error(`Agent is not running: ${agent.status}`);\n }\n\n const proc = this.processes.get(id);\n if (!proc || !proc.stdin) {\n throw new Error('Agent process not available');\n }\n\n proc.stdin.write(message + '\\n');\n this.log(id, 'info', `[USER] ${message}`);\n\n audit('agent.message_sent', null, 'agent', id, { length: message.length });\n }\n\n get(id: string): Agent | undefined {\n return this.agents.get(id);\n }\n\n list(includeStopped = false): Agent[] {\n const agents = Array.from(this.agents.values());\n if (includeStopped) return agents;\n return agents.filter((a) => a.status !== 'stopped');\n }\n\n log(agentId: string, level: string, message: string) {\n insertLog({ agentId, level, message });\n this.emit('agent:log', { agentId, level, message, timestamp: Date.now() });\n }\n\n getLogs(agentId: string, limit = 100) {\n return getLogs(agentId, limit);\n }\n\n getStats() {\n const agents = Array.from(this.agents.values());\n return {\n total: agents.length,\n running: agents.filter((a) => a.status === 'running').length,\n idle: agents.filter((a) => a.status === 'idle').length,\n stopped: agents.filter((a) => a.status === 'stopped').length,\n error: agents.filter((a) => a.status === 'error').length,\n };\n }\n}\n","import type { FastifyInstance } from 'fastify';\nimport { validateAuth, DirigentConfig } from '../config.js';\nimport { AgentManager } from '../agents/manager.js';\nimport { getAgents, audit } from '../db/index.js';\n\ninterface RouteOptions {\n config: DirigentConfig;\n agentManager: AgentManager;\n startTime: number;\n}\n\nexport function registerApiRoutes(server: FastifyInstance, options: RouteOptions) {\n const { config, agentManager, startTime } = options;\n\n // Auth middleware\n server.addHook('onRequest', async (request, reply) => {\n // Skip auth for health check\n if (request.url === '/health') return;\n\n // Skip auth for dashboard routes\n if (!request.url.startsWith('/api')) return;\n\n if (config.auth.enabled) {\n const authHeader = request.headers.authorization;\n const token = authHeader?.replace('Bearer ', '');\n\n if (!token || !validateAuth(token, config)) {\n reply.code(401).send({ error: 'Unauthorized' });\n return;\n }\n }\n });\n\n // Status\n server.get('/api/status', async () => {\n const stats = agentManager.getStats();\n const agents = agentManager.list(false);\n\n return {\n status: 'ok',\n uptime: Math.floor((Date.now() - startTime) / 1000),\n agents: {\n ...stats,\n list: agents.map((a) => ({\n id: a.id,\n name: a.name,\n template: a.template,\n status: a.status,\n workspace: a.workspace,\n currentTask: a.currentTask,\n })),\n },\n };\n });\n\n // List agents\n server.get<{ Querystring: { all?: string } }>('/api/agents', async (request) => {\n const includeStopped = request.query.all === 'true';\n const agents = agentManager.list(includeStopped);\n\n return {\n agents: agents.map((a) => ({\n id: a.id,\n name: a.name,\n template: a.template,\n status: a.status,\n workspace: a.workspace,\n model: a.model,\n pid: a.pid,\n currentTask: a.currentTask,\n createdAt: a.createdAt,\n startedAt: a.startedAt,\n stoppedAt: a.stoppedAt,\n error: a.error,\n })),\n };\n });\n\n // Spawn agent\n server.post<{\n Body: {\n template: string;\n name?: string;\n workspace?: string;\n task?: string;\n model?: string;\n };\n }>('/api/agents', async (request, reply) => {\n const { template, name, workspace, task, model } = request.body;\n\n if (!template) {\n reply.code(400).send({ error: 'template is required' });\n return;\n }\n\n try {\n const agent = await agentManager.spawn({ template, name, workspace, task, model });\n\n return {\n agent: {\n id: agent.id,\n name: agent.name,\n template: agent.template,\n status: agent.status,\n workspace: agent.workspace,\n model: agent.model,\n },\n };\n } catch (err: any) {\n reply.code(400).send({ error: err.message });\n }\n });\n\n // Get agent\n server.get<{ Params: { id: string } }>('/api/agents/:id', async (request, reply) => {\n const agent = agentManager.get(request.params.id);\n\n if (!agent) {\n reply.code(404).send({ error: 'Agent not found' });\n return;\n }\n\n return {\n agent: {\n id: agent.id,\n name: agent.name,\n template: agent.template,\n status: agent.status,\n workspace: agent.workspace,\n model: agent.model,\n pid: agent.pid,\n currentTask: agent.currentTask,\n createdAt: agent.createdAt,\n startedAt: agent.startedAt,\n stoppedAt: agent.stoppedAt,\n error: agent.error,\n },\n };\n });\n\n // Stop agent\n server.delete<{ Params: { id: string }; Querystring: { force?: string } }>(\n '/api/agents/:id',\n async (request, reply) => {\n const agent = agentManager.get(request.params.id);\n\n if (!agent) {\n reply.code(404).send({ error: 'Agent not found' });\n return;\n }\n\n const force = request.query.force === 'true';\n\n try {\n await agentManager.stop(request.params.id, force);\n return { ok: true };\n } catch (err: any) {\n reply.code(500).send({ error: err.message });\n }\n }\n );\n\n // Send message to agent\n server.post<{ Params: { id: string }; Body: { message: string } }>(\n '/api/agents/:id/send',\n async (request, reply) => {\n const agent = agentManager.get(request.params.id);\n\n if (!agent) {\n reply.code(404).send({ error: 'Agent not found' });\n return;\n }\n\n const { message } = request.body;\n\n if (!message) {\n reply.code(400).send({ error: 'message is required' });\n return;\n }\n\n try {\n await agentManager.send(request.params.id, message);\n return { ok: true };\n } catch (err: any) {\n reply.code(400).send({ error: err.message });\n }\n }\n );\n\n // Get agent logs\n server.get<{ Params: { id: string }; Querystring: { lines?: string } }>(\n '/api/agents/:id/logs',\n async (request, reply) => {\n const agent = agentManager.get(request.params.id);\n\n if (!agent) {\n reply.code(404).send({ error: 'Agent not found' });\n return;\n }\n\n const limit = parseInt(request.query.lines || '100');\n const logs = agentManager.getLogs(request.params.id, limit);\n\n return { logs };\n }\n );\n\n // Templates\n server.get('/api/templates', async () => {\n return {\n templates: Object.entries(config.agents.templates).map(([name, template]) => ({\n name,\n driver: template.driver,\n model: template.model,\n })),\n };\n });\n\n // Audit log\n server.get<{ Querystring: { limit?: string } }>('/api/audit', async (request) => {\n // TODO: Implement audit log retrieval\n return { logs: [] };\n });\n}\n","import type { FastifyInstance } from 'fastify';\nimport type { WebSocket } from 'ws';\nimport { validateAuth, DirigentConfig } from '../config.js';\nimport { AgentManager } from '../agents/manager.js';\n\ninterface WSOptions {\n config: DirigentConfig;\n agentManager: AgentManager;\n}\n\ninterface Client {\n ws: WebSocket;\n subscriptions: Set<string>;\n authenticated: boolean;\n}\n\nexport function registerWebSocket(server: FastifyInstance, options: WSOptions) {\n const { config, agentManager } = options;\n const clients: Map<string, Client> = new Map();\n\n // WebSocket route\n server.register(async (fastify) => {\n fastify.get('/ws', { websocket: true }, (connection, req) => {\n const ws = connection;\n const clientId = Math.random().toString(36).slice(2);\n\n const client: Client = {\n ws,\n subscriptions: new Set(),\n authenticated: !config.auth.enabled,\n };\n\n clients.set(clientId, client);\n\n ws.on('message', (data) => {\n try {\n const msg = JSON.parse(data.toString());\n handleMessage(clientId, client, msg);\n } catch (err) {\n send(ws, { type: 'error', error: 'Invalid JSON' });\n }\n });\n\n ws.on('close', () => {\n clients.delete(clientId);\n });\n\n ws.on('error', (err) => {\n console.error('WebSocket error:', err);\n clients.delete(clientId);\n });\n\n // Send welcome\n send(ws, {\n type: 'welcome',\n clientId,\n authenticated: client.authenticated,\n });\n });\n });\n\n function handleMessage(clientId: string, client: Client, msg: any) {\n // Auth\n if (msg.type === 'auth') {\n if (validateAuth(msg.token, config)) {\n client.authenticated = true;\n send(client.ws, { type: 'auth', success: true });\n } else {\n send(client.ws, { type: 'auth', success: false, error: 'Invalid token' });\n }\n return;\n }\n\n // Require auth for other messages\n if (!client.authenticated) {\n send(client.ws, { type: 'error', error: 'Not authenticated' });\n return;\n }\n\n switch (msg.type) {\n case 'subscribe:logs':\n if (msg.agentId) {\n client.subscriptions.add(`logs:${msg.agentId}`);\n send(client.ws, { type: 'subscribed', channel: `logs:${msg.agentId}` });\n }\n break;\n\n case 'unsubscribe:logs':\n if (msg.agentId) {\n client.subscriptions.delete(`logs:${msg.agentId}`);\n send(client.ws, { type: 'unsubscribed', channel: `logs:${msg.agentId}` });\n }\n break;\n\n case 'subscribe:agents':\n client.subscriptions.add('agents');\n send(client.ws, { type: 'subscribed', channel: 'agents' });\n break;\n\n case 'unsubscribe:agents':\n client.subscriptions.delete('agents');\n send(client.ws, { type: 'unsubscribed', channel: 'agents' });\n break;\n\n case 'ping':\n send(client.ws, { type: 'pong', ts: Date.now() });\n break;\n\n default:\n send(client.ws, { type: 'error', error: `Unknown message type: ${msg.type}` });\n }\n }\n\n // Agent event handlers\n agentManager.on('agent:created', (agent) => {\n broadcast('agents', { type: 'agent:created', agent: sanitizeAgent(agent) });\n });\n\n agentManager.on('agent:running', (agent) => {\n broadcast('agents', { type: 'agent:running', agent: sanitizeAgent(agent) });\n });\n\n agentManager.on('agent:stopped', (agent) => {\n broadcast('agents', { type: 'agent:stopped', agent: sanitizeAgent(agent) });\n });\n\n agentManager.on('agent:error', (agent, error) => {\n broadcast('agents', { type: 'agent:error', agent: sanitizeAgent(agent), error: error.message });\n });\n\n agentManager.on('agent:log', (data) => {\n broadcast(`logs:${data.agentId}`, { type: 'agent:log', ...data });\n });\n\n function broadcast(channel: string, message: object) {\n for (const client of clients.values()) {\n if (client.authenticated && client.subscriptions.has(channel)) {\n send(client.ws, message);\n }\n }\n }\n\n function send(ws: WebSocket, message: object) {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(message));\n }\n }\n\n function sanitizeAgent(agent: any) {\n return {\n id: agent.id,\n name: agent.name,\n template: agent.template,\n status: agent.status,\n workspace: agent.workspace,\n model: agent.model,\n pid: agent.pid,\n currentTask: agent.currentTask,\n createdAt: agent.createdAt,\n startedAt: agent.startedAt,\n stoppedAt: agent.stoppedAt,\n error: agent.error,\n };\n }\n}\n"],"mappings":"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","names":["join","existsSync","mkdirSync","join","existsSync","join","existsSync","server","agentManager","startTime","server","agentManager","join","mkdirSync","existsSync","db"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "diragent",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI Agent Orchestration Platform - Enterprise-grade orchestration for AI coding agents",
|
|
5
|
+
"author": "Anindya Roy <anindya@anindya.me>",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/anindyar/dirigent"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"ai",
|
|
13
|
+
"agent",
|
|
14
|
+
"orchestration",
|
|
15
|
+
"claude",
|
|
16
|
+
"codex",
|
|
17
|
+
"enterprise",
|
|
18
|
+
"llm"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"bin": {
|
|
22
|
+
"dirigent": "./dist/cli/index.js"
|
|
23
|
+
},
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"import": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts"
|
|
30
|
+
},
|
|
31
|
+
"./client": {
|
|
32
|
+
"import": "./dist/client/index.js",
|
|
33
|
+
"types": "./dist/client/index.d.ts"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"scripts",
|
|
39
|
+
"config"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsup",
|
|
43
|
+
"build:watch": "tsup --watch",
|
|
44
|
+
"dev": "tsx watch src/cli/index.ts",
|
|
45
|
+
"start": "node dist/cli/index.js",
|
|
46
|
+
"test": "vitest",
|
|
47
|
+
"lint": "eslint src",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"clean": "rm -rf dist",
|
|
50
|
+
"prepublishOnly": "npm run build"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"chalk": "^5.3.0",
|
|
54
|
+
"commander": "^12.1.0",
|
|
55
|
+
"conf": "^13.0.1",
|
|
56
|
+
"dotenv": "^16.4.5",
|
|
57
|
+
"express": "^4.21.0",
|
|
58
|
+
"fastify": "^5.0.0",
|
|
59
|
+
"@fastify/cors": "^10.0.1",
|
|
60
|
+
"@fastify/static": "^8.0.1",
|
|
61
|
+
"@fastify/websocket": "^11.0.1",
|
|
62
|
+
"nanoid": "^5.0.7",
|
|
63
|
+
"ora": "^8.1.0",
|
|
64
|
+
"pino": "^9.4.0",
|
|
65
|
+
"pino-pretty": "^11.2.2",
|
|
66
|
+
"socket.io": "^4.8.0",
|
|
67
|
+
"socket.io-client": "^4.8.0",
|
|
68
|
+
"better-sqlite3": "^11.3.0",
|
|
69
|
+
"yaml": "^2.5.1",
|
|
70
|
+
"zod": "^3.23.8",
|
|
71
|
+
"execa": "^9.4.0",
|
|
72
|
+
"tree-kill": "^1.2.2",
|
|
73
|
+
"ws": "^8.18.0",
|
|
74
|
+
"boxen": "^8.0.1",
|
|
75
|
+
"figures": "^6.1.0"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@types/better-sqlite3": "^7.6.11",
|
|
79
|
+
"@types/express": "^4.17.21",
|
|
80
|
+
"@types/node": "^22.7.4",
|
|
81
|
+
"@types/ws": "^8.5.12",
|
|
82
|
+
"tsup": "^8.3.0",
|
|
83
|
+
"tsx": "^4.19.1",
|
|
84
|
+
"typescript": "^5.6.2",
|
|
85
|
+
"vitest": "^2.1.1"
|
|
86
|
+
},
|
|
87
|
+
"engines": {
|
|
88
|
+
"node": ">=20.0.0"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
# Dirigent Installer
|
|
5
|
+
# Usage: curl -fsSL https://get.dirigent.dev | bash
|
|
6
|
+
|
|
7
|
+
REPO="anindyar/dirigent"
|
|
8
|
+
INSTALL_DIR="${DIRIGENT_INSTALL_DIR:-$HOME/.dirigent}"
|
|
9
|
+
BIN_DIR="${DIRIGENT_BIN_DIR:-$HOME/.local/bin}"
|
|
10
|
+
|
|
11
|
+
echo ""
|
|
12
|
+
echo " 🎭 Dirigent Installer"
|
|
13
|
+
echo " AI Agent Orchestration Platform"
|
|
14
|
+
echo ""
|
|
15
|
+
|
|
16
|
+
# Detect OS and arch
|
|
17
|
+
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
18
|
+
ARCH="$(uname -m)"
|
|
19
|
+
|
|
20
|
+
case "$ARCH" in
|
|
21
|
+
x86_64) ARCH="x64" ;;
|
|
22
|
+
aarch64 | arm64) ARCH="arm64" ;;
|
|
23
|
+
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
|
|
24
|
+
esac
|
|
25
|
+
|
|
26
|
+
case "$OS" in
|
|
27
|
+
linux | darwin) ;;
|
|
28
|
+
*) echo "Unsupported OS: $OS"; exit 1 ;;
|
|
29
|
+
esac
|
|
30
|
+
|
|
31
|
+
echo " OS: $OS"
|
|
32
|
+
echo " Arch: $ARCH"
|
|
33
|
+
echo ""
|
|
34
|
+
|
|
35
|
+
# Check for Node.js
|
|
36
|
+
if ! command -v node &> /dev/null; then
|
|
37
|
+
echo "❌ Node.js is required but not installed."
|
|
38
|
+
echo ""
|
|
39
|
+
echo "Install Node.js 20+ from: https://nodejs.org"
|
|
40
|
+
echo "Or use nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
NODE_VERSION=$(node -v | cut -d'.' -f1 | tr -d 'v')
|
|
45
|
+
if [ "$NODE_VERSION" -lt 20 ]; then
|
|
46
|
+
echo "❌ Node.js 20+ required (found: $(node -v))"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
echo " Node.js: $(node -v) ✓"
|
|
51
|
+
|
|
52
|
+
# Install via npm
|
|
53
|
+
echo ""
|
|
54
|
+
echo "Installing Dirigent..."
|
|
55
|
+
npm install -g dirigent@latest
|
|
56
|
+
|
|
57
|
+
echo ""
|
|
58
|
+
echo "✅ Dirigent installed successfully!"
|
|
59
|
+
echo ""
|
|
60
|
+
echo "Getting started:"
|
|
61
|
+
echo ""
|
|
62
|
+
echo " 1. Initialize: dirigent init"
|
|
63
|
+
echo " 2. Start: dirigent up"
|
|
64
|
+
echo " 3. Dashboard: http://localhost:3000"
|
|
65
|
+
echo ""
|
|
66
|
+
echo "Need help? https://github.com/$REPO"
|
|
67
|
+
echo ""
|