agentix-cli 0.2.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agent/skills/registry.ts","../src/agent/skills/generator.ts","../src/runtime/enhance.ts","../src/runtime/pipeline.ts","../src/runtime/server.ts","../src/mcp/index.ts","../src/git/manager.ts","../src/repl/session.ts","../src/repl/commands.ts","../src/repl/renderer.ts","../src/repl/engine.ts","../src/a2a/server.ts","../src/a2a/types.ts","../src/a2a/client.ts","../src/a2a/mesh.ts","../src/daemon/config.ts","../src/agents/runtime.ts","../src/agents/sessions.ts","../src/agents/registry.ts","../src/channels/router.ts","../src/channels/telegram-format.ts","../src/channels/telegram.ts","../src/channels/whatsapp.ts","../src/crons/scheduler.ts","../src/daemon/index.ts","../src/utils/handle-error.ts","../src/utils/get-package-info.ts"],"sourcesContent":["import { execa } from \"execa\"\nimport { existsSync, promises as fs } from \"fs\"\nimport path from \"path\"\nimport fetch from \"node-fetch\"\nimport { logger } from \"@/utils/logger\"\nimport type { Skill, SkillPackage } from \"./types\"\nimport { parseSkillContent } from \"./loader\"\n\n// --- skills.sh integration: install, list, and search skills ---\n\nconst SKILLS_SH_API = \"https://skills.sh\"\n\nexport async function installSkillPackage(\n packageId: string,\n cwd: string\n): Promise<Skill[]> {\n // packageId format: \"owner/repo\" or \"owner/repo/skill-name\"\n const parts = packageId.split(\"/\")\n if (parts.length < 2) {\n throw new Error(`Invalid skill package ID: ${packageId}. Expected format: owner/repo`)\n }\n\n const owner = parts[0]\n const repo = parts[1]\n const specificSkill = parts[2] // optional\n\n // Try using npx skills add first (official CLI)\n try {\n const skillArg = specificSkill ? `${owner}/${repo}/${specificSkill}` : `${owner}/${repo}`\n await execa(\"npx\", [\"-y\", \"skills\", \"add\", skillArg], {\n cwd,\n stdio: \"pipe\",\n })\n\n logger.success(`Installed skill package: ${packageId}`)\n\n // Load the installed skills\n const skillsDir = path.resolve(cwd, \".skills\", `${owner}_${repo}`)\n if (existsSync(skillsDir)) {\n return await loadInstalledSkills(skillsDir, packageId)\n }\n\n // Also check the standard .skills directory structure\n const altDir = path.resolve(cwd, \".skills\")\n if (existsSync(altDir)) {\n return await loadInstalledSkills(altDir, packageId)\n }\n\n return []\n } catch {\n // Fallback: fetch directly from GitHub\n logger.info(`Fetching skills directly from GitHub: ${owner}/${repo}`)\n return await fetchFromGitHub(owner, repo, specificSkill, cwd)\n }\n}\n\nasync function fetchFromGitHub(\n owner: string,\n repo: string,\n specificSkill: string | undefined,\n cwd: string\n): Promise<Skill[]> {\n const skills: Skill[] = []\n\n try {\n // Fetch repo tree to find SKILL.md files\n const treeUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/main?recursive=1`\n const response = await fetch(treeUrl)\n\n if (!response.ok) {\n throw new Error(`GitHub API error: ${response.status}`)\n }\n\n const data = (await response.json()) as { tree: { path: string; type: string }[] }\n const skillFiles = data.tree.filter(\n (item) => item.type === \"blob\" && item.path.endsWith(\"SKILL.md\")\n )\n\n if (specificSkill) {\n const specific = skillFiles.find(\n (f) =>\n f.path.includes(`/${specificSkill}/`) || f.path === `${specificSkill}/SKILL.md`\n )\n if (specific) {\n const skill = await fetchAndSaveSkill(owner, repo, specific.path, cwd)\n if (skill) skills.push(skill)\n }\n } else {\n for (const file of skillFiles) {\n const skill = await fetchAndSaveSkill(owner, repo, file.path, cwd)\n if (skill) skills.push(skill)\n }\n }\n } catch (error: any) {\n logger.error(`Failed to fetch skills from GitHub: ${error.message}`)\n }\n\n return skills\n}\n\nasync function fetchAndSaveSkill(\n owner: string,\n repo: string,\n filePath: string,\n cwd: string\n): Promise<Skill | null> {\n try {\n const rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/main/${filePath}`\n const response = await fetch(rawUrl)\n\n if (!response.ok) return null\n\n const content = await response.text()\n const skill = parseSkillContent(content)\n\n if (skill) {\n skill.source = \"remote\"\n skill.packageId = `${owner}/${repo}`\n\n // Save locally\n const skillDir = path.dirname(filePath)\n const localDir = path.resolve(cwd, \".skills\", `${owner}_${repo}`, skillDir)\n await fs.mkdir(localDir, { recursive: true })\n await fs.writeFile(path.resolve(localDir, \"SKILL.md\"), content)\n skill.path = path.resolve(localDir, \"SKILL.md\")\n }\n\n return skill\n } catch {\n return null\n }\n}\n\nasync function loadInstalledSkills(dir: string, packageId: string): Promise<Skill[]> {\n const skills: Skill[] = []\n const { default: fg } = await import(\"fast-glob\")\n\n const skillFiles = await fg.glob(\"**/SKILL.md\", {\n cwd: dir,\n deep: 5,\n })\n\n for (const file of skillFiles) {\n try {\n const fullPath = path.resolve(dir, file)\n const content = await fs.readFile(fullPath, \"utf8\")\n const skill = parseSkillContent(content)\n if (skill) {\n skill.source = \"remote\"\n skill.path = fullPath\n skill.packageId = packageId\n skills.push(skill)\n }\n } catch {\n // Skip broken skill files\n }\n }\n\n return skills\n}\n\nexport async function generateSkillMd(\n name: string,\n description: string,\n instructions: string,\n tags?: string[],\n globs?: string[]\n): Promise<string> {\n const frontmatter: string[] = [\n \"---\",\n `name: ${name}`,\n `description: ${description}`,\n ]\n\n if (tags?.length) {\n frontmatter.push(\"tags:\")\n for (const tag of tags) {\n frontmatter.push(` - ${tag}`)\n }\n }\n\n if (globs?.length) {\n frontmatter.push(\"globs:\")\n for (const glob of globs) {\n frontmatter.push(` - ${glob}`)\n }\n }\n\n frontmatter.push(\"---\")\n\n return `${frontmatter.join(\"\\n\")}\\n\\n${instructions}`\n}\n\nexport async function listInstalledSkills(cwd: string): Promise<Skill[]> {\n const { loadLocalSkills } = await import(\"./loader\")\n return loadLocalSkills(cwd)\n}\n","import type { AgentProvider, GenerationMessage } from \"../providers/types\"\nimport type { TechStack } from \"../context/tech-stack\"\nimport { formatTechStack } from \"../context/tech-stack\"\nimport { generateSkillMd } from \"./registry\"\nimport type { Skill } from \"./types\"\n\n// --- Generate new skills using AI ---\n\nexport async function generateSkill(\n provider: AgentProvider,\n name: string,\n description: string,\n techStack: TechStack,\n options?: { tags?: string[]; outputType?: string }\n): Promise<{ skill: Skill; content: string }> {\n const systemPrompt = `You are a skill author for the Agent Skills ecosystem (skills.sh).\nYou create high-quality SKILL.md files that provide reusable instructions for AI coding agents.\n\nA skill is a markdown document with YAML frontmatter that teaches an agent how to perform a specific task.\nSkills should be:\n- Clear and actionable\n- Tech-stack aware (use the right patterns for the project)\n- Complete but concise\n- Include examples where helpful\n- Follow the Agent Skills specification\n\nThe project's tech stack:\n${formatTechStack(techStack)}\n\nOutput ONLY the SKILL.md content (frontmatter + markdown instructions). Do not wrap in code fences.`\n\n const messages: GenerationMessage[] = [\n { role: \"system\", content: systemPrompt },\n {\n role: \"user\",\n content: `Create a skill called \"${name}\" with this description: \"${description}\"${\n options?.tags?.length ? `\\nTags: ${options.tags.join(\", \")}` : \"\"\n }${options?.outputType ? `\\nPrimary output type: ${options.outputType}` : \"\"}\n\nThe skill should contain detailed instructions for an AI agent to follow when performing this task in a project with the above tech stack. Include:\n1. Step-by-step instructions\n2. Code patterns and conventions to follow\n3. Common pitfalls to avoid\n4. Examples where helpful`,\n },\n ]\n\n const result = await provider.generate(messages, {\n temperature: 0.7,\n maxTokens: 4096,\n })\n\n const skillContent = result.content.trim()\n\n // Parse the generated content\n const skill: Skill = {\n frontmatter: { name, description },\n instructions: skillContent,\n source: \"generated\",\n }\n\n // Try to parse the frontmatter from generated content\n const frontmatterMatch = skillContent.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/)\n if (frontmatterMatch) {\n skill.instructions = frontmatterMatch[2].trim()\n }\n\n return { skill, content: skillContent }\n}\n","import { existsSync, promises as fs } from \"fs\"\nimport path from \"path\"\nimport { createProvider, type ProviderName } from \"@/agent/providers\"\nimport type { GenerationMessage } from \"@/agent/providers/types\"\nimport { detectTechStack, formatTechStack } from \"@/agent/context/tech-stack\"\nimport { Memory, type MemoryEntry, type LearnedPattern } from \"./memory\"\nimport { generateSkillMd } from \"@/agent/skills/registry\"\n\n// --- Self-Enhancement: auto-create skills from successful patterns ---\n// After enough successful generations with positive feedback,\n// the system distills what worked into reusable skills.\n// It also detects degradation and triggers skill upgrades.\n\nexport interface EnhanceConfig {\n enabled: boolean\n autoSkills: boolean // Auto-create skills from patterns\n minFrequency: number // Min pattern frequency before creating a skill\n provider: ProviderName\n model?: string\n apiKey?: string\n}\n\nexport interface EnhanceResult {\n skillsCreated: string[]\n skillsUpdated: string[]\n insights: string[]\n}\n\nconst DEFAULT_CONFIG: EnhanceConfig = {\n enabled: true,\n autoSkills: true,\n minFrequency: 3,\n provider: \"claude-code\",\n}\n\nexport class EnhanceEngine {\n private config: EnhanceConfig\n\n constructor(\n private cwd: string,\n private memory: Memory,\n config?: Partial<EnhanceConfig>\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config }\n }\n\n async enhance(): Promise<EnhanceResult> {\n if (!this.config.enabled) {\n return { skillsCreated: [], skillsUpdated: [], insights: [] }\n }\n\n const result: EnhanceResult = {\n skillsCreated: [],\n skillsUpdated: [],\n insights: [],\n }\n\n // 1. Analyze patterns and create skills\n if (this.config.autoSkills) {\n const newSkills = await this.createSkillsFromPatterns()\n result.skillsCreated.push(...newSkills)\n }\n\n // 2. Analyze failure patterns for insights\n const insights = this.analyzeFailures()\n result.insights.push(...insights)\n\n // 3. Detect preference patterns\n const prefInsights = this.analyzePreferences()\n result.insights.push(...prefInsights)\n\n return result\n }\n\n private async createSkillsFromPatterns(): Promise<string[]> {\n const patterns = this.memory.getPatterns()\n const eligiblePatterns = patterns.filter(\n (p) => p.frequency >= this.config.minFrequency\n )\n\n if (!eligiblePatterns.length) return []\n\n const created: string[] = []\n const skillsDir = path.resolve(this.cwd, \".skills\", \"_auto\")\n\n for (const pattern of eligiblePatterns.slice(0, 3)) {\n const skillName = patternToSkillName(pattern)\n const skillPath = path.resolve(skillsDir, skillName, \"SKILL.md\")\n\n // Don't recreate existing skills\n if (existsSync(skillPath)) continue\n\n try {\n const content = await this.generateSkillFromPattern(pattern)\n if (content) {\n await fs.mkdir(path.dirname(skillPath), { recursive: true })\n await fs.writeFile(skillPath, content, \"utf8\")\n created.push(skillName)\n }\n } catch {\n // Skip failed skill generation\n }\n }\n\n return created\n }\n\n private async generateSkillFromPattern(pattern: LearnedPattern): Promise<string | null> {\n // Get examples of successful generations matching this pattern\n const recentSuccesses = this.memory\n .getRecentGenerations(20)\n .filter((e) => e.success && e.userFeedback !== \"negative\")\n .slice(0, 3)\n\n if (!recentSuccesses.length) return null\n\n const provider = createProvider(this.config.provider, this.config.apiKey)\n const techStack = await detectTechStack(this.cwd)\n\n const messages: GenerationMessage[] = [\n {\n role: \"system\",\n content: `You are a skill author. Create a SKILL.md file that captures a successful pattern.\nTech stack: ${formatTechStack(techStack)}\nOutput ONLY the SKILL.md content with YAML frontmatter. No code fences.`,\n },\n {\n role: \"user\",\n content: `Create a skill from this recurring pattern:\n\nPattern: ${pattern.description}\nFrequency: used ${pattern.frequency} times\nTech stack: ${pattern.techStack.join(\", \") || \"general\"}\n\nSuccessful examples:\n${recentSuccesses.map((e) => `- \"${e.task}\" → ${e.files.join(\", \")}`).join(\"\\n\")}\n\nCreate a concise, reusable skill that captures what worked.`,\n },\n ]\n\n const result = await provider.generate(messages, {\n maxTokens: 2048,\n temperature: 0.7,\n })\n\n return result.content.trim() || null\n }\n\n private analyzeFailures(): string[] {\n const insights: string[] = []\n const failures = this.memory.getFailedGenerations(20)\n\n if (failures.length < 2) return insights\n\n // Group failures by error pattern\n const errorGroups = new Map<string, MemoryEntry[]>()\n for (const f of failures) {\n const key = (f.error || \"unknown\").split(\"\\n\")[0].slice(0, 80)\n const group = errorGroups.get(key) || []\n group.push(f)\n errorGroups.set(key, group)\n }\n\n for (const [error, entries] of errorGroups) {\n if (entries.length >= 2) {\n insights.push(\n `Recurring error (${entries.length}x): \"${error}\" — consider creating a skill to prevent this`\n )\n }\n }\n\n // Success rate trending down\n const stats = this.memory.getStats()\n if (stats.successRate < 0.7 && stats.totalGenerations > 5) {\n insights.push(\n `Success rate is ${(stats.successRate * 100).toFixed(0)}% — review recent failures and update skills`\n )\n }\n\n return insights\n }\n\n private analyzePreferences(): string[] {\n const insights: string[] = []\n const prefs = this.memory.getPreferences()\n\n const highConfidence = prefs.filter((p) => p.confidence > 0.8)\n if (highConfidence.length) {\n insights.push(\n `Strong preferences detected: ${highConfidence.map((p) => `${p.key}=${p.value}`).join(\", \")}`\n )\n }\n\n return insights\n }\n}\n\nfunction patternToSkillName(pattern: LearnedPattern): string {\n return pattern.description\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .slice(0, 40)\n .replace(/-+$/, \"\")\n}\n","import type { AgentContext } from \"@/agent\"\nimport type { Memory } from \"./memory\"\n\n// --- Agent Pipeline: middleware chain like Laravel/Express ---\n// Request → Auth → Context → Memory → Skills → Agent → Validate → Heal → Enhance → Response\n\nexport interface PipelineRequest {\n id: string\n task: string\n outputType?: string\n outputDir?: string\n provider?: string\n model?: string\n apiKey?: string\n cwd: string\n overwrite?: boolean\n metadata?: Record<string, unknown>\n}\n\nexport interface PipelineResponse {\n id: string\n success: boolean\n files: { path: string; content?: string }[]\n content: string\n outputType: string\n error?: string\n healed?: boolean\n healAttempts?: number\n tokensUsed?: number\n memoryEntryId?: string\n insights?: string[]\n duration: number\n}\n\nexport type MiddlewareFn = (\n req: PipelineRequest,\n res: PipelineResponse,\n context: PipelineContext,\n next: () => Promise<void>\n) => Promise<void>\n\nexport interface PipelineContext {\n agentContext?: AgentContext\n memory?: Memory\n startTime: number\n [key: string]: unknown\n}\n\nexport class Pipeline {\n private middleware: { name: string; fn: MiddlewareFn }[] = []\n\n use(name: string, fn: MiddlewareFn): Pipeline {\n this.middleware.push({ name, fn })\n return this\n }\n\n async execute(req: PipelineRequest): Promise<PipelineResponse> {\n const res: PipelineResponse = {\n id: req.id,\n success: false,\n files: [],\n content: \"\",\n outputType: req.outputType || \"auto\",\n duration: 0,\n }\n\n const context: PipelineContext = {\n startTime: Date.now(),\n }\n\n let index = 0\n\n const next = async (): Promise<void> => {\n if (index >= this.middleware.length) return\n const mw = this.middleware[index++]\n await mw.fn(req, res, context, next)\n }\n\n try {\n await next()\n res.duration = Date.now() - context.startTime\n } catch (error: any) {\n res.success = false\n res.error = error.message\n res.duration = Date.now() - context.startTime\n }\n\n return res\n }\n\n getMiddlewareNames(): string[] {\n return this.middleware.map((m) => m.name)\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"http\"\nimport { createAgentContext, generate } from \"@/agent\"\nimport type { ProviderName } from \"@/agent/providers\"\nimport { Memory } from \"./memory\"\nimport { HealEngine } from \"./heal\"\nimport { EnhanceEngine } from \"./enhance\"\nimport { Pipeline, type PipelineRequest, type PipelineResponse, type MiddlewareFn } from \"./pipeline\"\nimport { detectTechStack, formatTechStack } from \"@/agent/context/tech-stack\"\n\n// --- Runtime Server: HTTP server that receives requests and sends responses ---\n// Like Laravel, but every request is powered by AI agents.\n// The server learns, heals, and enhances itself over time.\n\nexport interface RuntimeConfig {\n port: number\n host: string\n provider: ProviderName\n model?: string\n apiKey?: string\n cwd: string\n memory: { enabled: boolean }\n heal: {\n enabled: boolean\n testCommand?: string\n buildCommand?: string\n }\n enhance: { enabled: boolean; autoSkills: boolean }\n cors: boolean\n}\n\nconst DEFAULT_CONFIG: RuntimeConfig = {\n port: 3170,\n host: \"0.0.0.0\",\n provider: \"claude-code\",\n cwd: process.cwd(),\n memory: { enabled: true },\n heal: { enabled: true },\n enhance: { enabled: true, autoSkills: true },\n cors: true,\n}\n\nexport class AgentXRuntime {\n private config: RuntimeConfig\n private memory: Memory\n private healEngine: HealEngine\n private enhanceEngine: EnhanceEngine\n private pipeline: Pipeline\n private requestCount = 0\n private log: (...args: unknown[]) => void\n\n constructor(config?: Partial<RuntimeConfig>) {\n this.config = { ...DEFAULT_CONFIG, ...config }\n this.memory = new Memory(this.config.cwd)\n this.healEngine = new HealEngine(this.config.cwd, {\n enabled: this.config.heal.enabled,\n testCommand: this.config.heal.testCommand,\n buildCommand: this.config.heal.buildCommand,\n provider: this.config.provider,\n model: this.config.model,\n apiKey: this.config.apiKey,\n })\n this.enhanceEngine = new EnhanceEngine(this.config.cwd, this.memory, {\n enabled: this.config.enhance.enabled,\n autoSkills: this.config.enhance.autoSkills,\n provider: this.config.provider,\n model: this.config.model,\n apiKey: this.config.apiKey,\n })\n this.pipeline = this.buildPipeline()\n this.log = console.error.bind(console, \"[agentx]\")\n }\n\n private buildPipeline(): Pipeline {\n const pipeline = new Pipeline()\n\n // 1. Memory loading\n pipeline.use(\"memory\", this.memoryMiddleware())\n\n // 2. Context gathering\n pipeline.use(\"context\", this.contextMiddleware())\n\n // 3. Generation\n pipeline.use(\"generate\", this.generateMiddleware())\n\n // 4. Auto-heal\n pipeline.use(\"heal\", this.healMiddleware())\n\n // 5. Memory recording\n pipeline.use(\"record\", this.recordMiddleware())\n\n // 6. Enhancement check\n pipeline.use(\"enhance\", this.enhanceMiddleware())\n\n return pipeline\n }\n\n async start(): Promise<void> {\n await this.memory.load()\n\n const server = createServer(async (req, res) => {\n if (this.config.cors) {\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\")\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\")\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\")\n if (req.method === \"OPTIONS\") {\n res.writeHead(204)\n res.end()\n return\n }\n }\n\n await this.handleRequest(req, res)\n })\n\n server.listen(this.config.port, this.config.host, () => {\n this.log(`\\n agentx runtime v0.1.0`)\n this.log(` Listening on http://${this.config.host}:${this.config.port}`)\n this.log(` Provider: ${this.config.provider}`)\n this.log(` Memory: ${this.config.memory.enabled ? \"enabled\" : \"disabled\"}`)\n this.log(` Auto-heal: ${this.config.heal.enabled ? \"enabled\" : \"disabled\"}`)\n this.log(` Self-enhance: ${this.config.enhance.enabled ? \"enabled\" : \"disabled\"}`)\n this.log(` Pipeline: ${this.pipeline.getMiddlewareNames().join(\" → \")}`)\n this.log(` Working dir: ${this.config.cwd}`)\n this.log(\"\")\n this.log(\" Endpoints:\")\n this.log(\" POST /generate — generate code/content\")\n this.log(\" POST /evolve — transform existing code\")\n this.log(\" GET /inspect — project analysis\")\n this.log(\" GET /memory — view learning history\")\n this.log(\" POST /feedback — provide feedback on a generation\")\n this.log(\" GET /health — health check\")\n this.log(\" POST /enhance — trigger self-enhancement\")\n this.log(\"\")\n })\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url || \"/\", `http://${req.headers.host || \"localhost\"}`)\n const method = req.method || \"GET\"\n const pathname = url.pathname\n\n this.log(`${method} ${pathname}`)\n\n try {\n switch (`${method} ${pathname}`) {\n case \"POST /generate\":\n await this.handleGenerate(req, res)\n break\n case \"POST /evolve\":\n await this.handleEvolve(req, res)\n break\n case \"GET /inspect\":\n await this.handleInspect(res)\n break\n case \"GET /memory\":\n await this.handleMemory(res)\n break\n case \"POST /feedback\":\n await this.handleFeedback(req, res)\n break\n case \"GET /health\":\n this.sendJson(res, 200, {\n status: \"ok\",\n uptime: process.uptime(),\n requests: this.requestCount,\n stats: this.memory.getStats(),\n pipeline: this.pipeline.getMiddlewareNames(),\n })\n break\n case \"POST /enhance\":\n await this.handleEnhance(res)\n break\n default:\n this.sendJson(res, 404, {\n error: \"Not found\",\n endpoints: [\n \"POST /generate\",\n \"POST /evolve\",\n \"GET /inspect\",\n \"GET /memory\",\n \"POST /feedback\",\n \"GET /health\",\n \"POST /enhance\",\n ],\n })\n }\n } catch (error: any) {\n this.log(\"Error:\", error.message)\n this.sendJson(res, 500, { error: error.message })\n }\n\n this.requestCount++\n }\n\n private async handleGenerate(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const body = await readBody(req)\n if (!body.task) {\n this.sendJson(res, 400, { error: \"Missing required field: task\" })\n return\n }\n\n const pipelineReq: PipelineRequest = {\n id: `req-${Date.now().toString(36)}`,\n task: body.task,\n outputType: body.type || body.outputType || \"auto\",\n outputDir: body.outputDir || body.output_dir,\n provider: body.provider || this.config.provider,\n model: body.model || this.config.model,\n apiKey: body.apiKey || body.api_key || this.config.apiKey,\n cwd: this.config.cwd,\n overwrite: body.overwrite ?? true,\n metadata: body.metadata,\n }\n\n const result = await this.pipeline.execute(pipelineReq)\n this.sendJson(res, result.success ? 200 : 500, result)\n }\n\n private async handleEvolve(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const body = await readBody(req)\n if (!body.task || !body.glob) {\n this.sendJson(res, 400, {\n error: \"Missing required fields: task, glob\",\n })\n return\n }\n\n // Evolve uses the same pipeline but with file reading\n this.sendJson(res, 200, {\n message: \"Use the CLI for evolve: agentx evolve \\\"\" + body.task + \"\\\" --glob \\\"\" + body.glob + \"\\\"\",\n hint: \"The evolve endpoint requires interactive diff review. Use the CLI for full functionality.\",\n })\n }\n\n private async handleInspect(res: ServerResponse): Promise<void> {\n const context = await createAgentContext(this.config.cwd, \"inspect\", {\n context7: { enabled: false },\n })\n\n this.sendJson(res, 200, {\n techStack: {\n languages: context.techStack.languages,\n frameworks: context.techStack.frameworks,\n packageManager: context.techStack.packageManager,\n databases: context.techStack.databases,\n styling: context.techStack.styling,\n testing: context.techStack.testing,\n deployment: context.techStack.deployment,\n monorepo: context.techStack.monorepo,\n },\n schemas: {\n database: context.schemas.database\n ? { type: context.schemas.database.type, tables: context.schemas.database.tables }\n : null,\n api: context.schemas.api ? { type: context.schemas.api.type } : null,\n env: context.schemas.env,\n models: context.schemas.models?.map((m) => ({ path: m.path, type: m.type })),\n },\n skills: context.skills.map((s) => ({\n name: s.frontmatter.name,\n description: s.frontmatter.description,\n source: s.source,\n tags: s.frontmatter.tags,\n })),\n dependencies: Object.keys(context.techStack.dependencies).length,\n devDependencies: Object.keys(context.techStack.devDependencies).length,\n })\n }\n\n private async handleMemory(res: ServerResponse): Promise<void> {\n this.sendJson(res, 200, {\n stats: this.memory.getStats(),\n recent: this.memory.getRecentGenerations(10),\n patterns: this.memory.getPatterns().slice(0, 10),\n preferences: this.memory.getPreferences(),\n })\n }\n\n private async handleFeedback(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const body = await readBody(req)\n if (!body.entryId || !body.feedback) {\n this.sendJson(res, 400, {\n error: \"Missing required fields: entryId, feedback (positive/negative/neutral)\",\n })\n return\n }\n\n await this.memory.recordFeedback(body.entryId, body.feedback)\n this.sendJson(res, 200, { recorded: true })\n }\n\n private async handleEnhance(res: ServerResponse): Promise<void> {\n const result = await this.enhanceEngine.enhance()\n this.sendJson(res, 200, result)\n }\n\n // --- Middleware factories ---\n\n private memoryMiddleware(): MiddlewareFn {\n const memory = this.memory\n return async (req, res, ctx, next) => {\n ctx.memory = memory\n const memoryContext = memory.buildMemoryContext(req.task)\n if (memoryContext) {\n ctx.memoryContext = memoryContext\n }\n await next()\n }\n }\n\n private contextMiddleware(): MiddlewareFn {\n return async (req, res, ctx, next) => {\n ctx.agentContext = await createAgentContext(req.cwd, req.task, {\n provider: req.provider as any,\n context7: { enabled: true },\n })\n await next()\n }\n }\n\n private generateMiddleware(): MiddlewareFn {\n return async (req, res, ctx, next) => {\n const result = await generate({\n task: ctx.memoryContext\n ? `${req.task}\\n\\n${ctx.memoryContext}`\n : req.task,\n outputType: req.outputType as any,\n outputDir: req.outputDir,\n overwrite: req.overwrite ?? true,\n cwd: req.cwd,\n provider: (req.provider || this.config.provider) as any,\n model: req.model || this.config.model,\n apiKey: req.apiKey || this.config.apiKey,\n context7: true,\n interactive: false,\n maxSteps: 5,\n })\n\n res.success = result.files.errors.length === 0\n res.files = result.files.written.map((f) => ({ path: f }))\n res.content = result.content\n res.outputType = result.outputType\n res.tokensUsed = result.tokensUsed\n\n await next()\n }\n }\n\n private healMiddleware(): MiddlewareFn {\n const healEngine = this.healEngine\n return async (req, res, ctx, next) => {\n if (this.config.heal.enabled && res.files.length > 0) {\n const healResult = await healEngine.detectAndHeal(\n res.files.map((f) => f.path),\n req.task,\n res.memoryEntryId\n )\n if (healResult.attempts > 0) {\n res.healed = healResult.healed\n res.healAttempts = healResult.attempts\n if (healResult.healed) {\n res.success = true\n }\n }\n }\n await next()\n }\n }\n\n private recordMiddleware(): MiddlewareFn {\n const memory = this.memory\n return async (req, res, ctx, next) => {\n if (this.config.memory.enabled) {\n const entryId = await memory.recordGeneration({\n task: req.task,\n outputType: res.outputType,\n files: res.files.map((f) => f.path),\n success: res.success,\n error: res.error,\n context: {\n techStack: ctx.agentContext?.techStack.languages.map((l) => l.name),\n frameworks: ctx.agentContext?.techStack.frameworks.map((f) => f.name),\n },\n })\n res.memoryEntryId = entryId\n\n // Learn preferences from request patterns\n if (req.outputType && req.outputType !== \"auto\") {\n await memory.learnPreference(\n \"preferred-output-type\",\n req.outputType,\n `generation request: ${req.task.slice(0, 50)}`\n )\n }\n }\n await next()\n }\n }\n\n private enhanceMiddleware(): MiddlewareFn {\n const enhanceEngine = this.enhanceEngine\n return async (req, res, ctx, next) => {\n // Run enhancement in background every 10 requests\n if (this.config.enhance.enabled && this.requestCount % 10 === 0 && this.requestCount > 0) {\n enhanceEngine.enhance().then((result) => {\n if (result.skillsCreated.length) {\n this.log(`Auto-created ${result.skillsCreated.length} skill(s): ${result.skillsCreated.join(\", \")}`)\n }\n if (result.insights.length) {\n for (const insight of result.insights) {\n this.log(`Insight: ${insight}`)\n }\n }\n }).catch(() => {})\n }\n await next()\n }\n }\n\n private sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" })\n res.end(JSON.stringify(data, null, 2))\n }\n}\n\nasync function readBody(req: IncomingMessage): Promise<Record<string, any>> {\n return new Promise((resolve, reject) => {\n let body = \"\"\n req.on(\"data\", (chunk) => (body += chunk))\n req.on(\"end\", () => {\n try {\n resolve(body ? JSON.parse(body) : {})\n } catch {\n resolve({})\n }\n })\n req.on(\"error\", reject)\n })\n}\n","import { createAgentContext } from \"@/agent\"\nimport { detectTechStack, formatTechStack } from \"@/agent/context/tech-stack\"\nimport { detectSchemas, formatSchemas } from \"@/agent/context/schema\"\nimport { loadLocalSkills, matchSkillsToTask } from \"@/agent/skills/loader\"\nimport { resolveOutputType } from \"@/agent/outputs/types\"\nimport { generate } from \"@/agent\"\nimport type { OutputType } from \"@/agent/providers/types\"\n\n// --- MCP Server: expose agentx as a Model Context Protocol server ---\n// This allows Claude Code, Cursor, Windsurf, and any MCP client to use\n// agentx's capabilities as tools.\n\n// JSON-RPC types\ninterface JsonRpcRequest {\n jsonrpc: \"2.0\"\n id: number | string\n method: string\n params?: Record<string, unknown>\n}\n\ninterface JsonRpcResponse {\n jsonrpc: \"2.0\"\n id: number | string | null\n result?: unknown\n error?: { code: number; message: string; data?: unknown }\n}\n\ninterface JsonRpcNotification {\n jsonrpc: \"2.0\"\n method: string\n params?: Record<string, unknown>\n}\n\n// MCP protocol constants\nconst SERVER_INFO = {\n name: \"agentx\",\n version: \"0.1.0\",\n}\n\nconst PROTOCOL_VERSION = \"2024-11-05\"\n\nconst CAPABILITIES = {\n tools: {},\n}\n\n// Tool definitions\nconst TOOLS = [\n {\n name: \"agentx_generate\",\n description:\n \"Generate code, components, pages, APIs, documents, tests, workflows, schemas, emails, diagrams, and more using AI. Understands the project's tech stack, schemas, and skills automatically.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n task: {\n type: \"string\",\n description:\n \"Describe what to generate (e.g., 'a responsive pricing card', 'REST API for users', 'GitHub Actions CI pipeline')\",\n },\n type: {\n type: \"string\",\n description:\n \"Output type: component, page, api, website, document, script, config, skill, media, report, test, workflow, schema, email, diagram, auto\",\n default: \"auto\",\n },\n output_dir: {\n type: \"string\",\n description: \"Optional output directory (relative to project root)\",\n },\n cwd: {\n type: \"string\",\n description: \"Project working directory (defaults to current directory)\",\n },\n },\n required: [\"task\"],\n },\n },\n {\n name: \"agentx_inspect\",\n description:\n \"Analyze a project and return its tech stack, frameworks, databases, schemas, installed skills, and dependencies. Use this to understand a project before generating code.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n cwd: {\n type: \"string\",\n description: \"Project working directory (defaults to current directory)\",\n },\n },\n },\n },\n {\n name: \"agentx_skill_match\",\n description:\n \"Find installed skills that are relevant to a given task description. Returns matched skills with relevance scores.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n task: {\n type: \"string\",\n description: \"The task to match skills against\",\n },\n cwd: {\n type: \"string\",\n description: \"Project working directory\",\n },\n },\n required: [\"task\"],\n },\n },\n {\n name: \"agentx_detect_output_type\",\n description:\n \"Auto-detect the best output type for a given task description based on keyword analysis.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n task: {\n type: \"string\",\n description: \"The task description to analyze\",\n },\n },\n required: [\"task\"],\n },\n },\n]\n\n// Tool handlers\nasync function handleToolCall(\n name: string,\n args: Record<string, unknown>\n): Promise<{ content: { type: string; text: string }[] }> {\n const cwd = (args.cwd as string) || process.cwd()\n\n switch (name) {\n case \"agentx_generate\": {\n const task = args.task as string\n const outputType = (args.type as string) || \"auto\"\n const outputDir = args.output_dir as string | undefined\n\n const result = await generate({\n task,\n outputType: outputType as OutputType,\n outputDir,\n cwd,\n overwrite: true,\n dryRun: false,\n context7: true,\n interactive: false,\n maxSteps: 5,\n })\n\n const summary: string[] = []\n if (result.content) summary.push(result.content)\n if (result.files.written.length) {\n summary.push(\n `\\nCreated ${result.files.written.length} file(s):\\n${result.files.written.map((f) => ` - ${f}`).join(\"\\n\")}`\n )\n }\n if (result.files.skipped.length) {\n summary.push(\n `\\nSkipped ${result.files.skipped.length} existing file(s):\\n${result.files.skipped.map((f) => ` - ${f}`).join(\"\\n\")}`\n )\n }\n if (result.followUp) {\n summary.push(`\\nNeeds clarification: ${result.followUp}`)\n }\n\n return {\n content: [{ type: \"text\", text: summary.join(\"\\n\") || \"Generation complete.\" }],\n }\n }\n\n case \"agentx_inspect\": {\n const context = await createAgentContext(cwd, \"inspect\", {\n context7: { enabled: false },\n })\n\n const info: Record<string, unknown> = {\n languages: context.techStack.languages,\n frameworks: context.techStack.frameworks,\n packageManager: context.techStack.packageManager,\n databases: context.techStack.databases,\n styling: context.techStack.styling,\n testing: context.techStack.testing,\n deployment: context.techStack.deployment,\n monorepo: context.techStack.monorepo,\n srcDir: context.techStack.srcDir,\n dependencyCount: Object.keys(context.techStack.dependencies).length,\n devDependencyCount: Object.keys(context.techStack.devDependencies).length,\n schemas: {\n database: context.schemas.database\n ? {\n type: context.schemas.database.type,\n tables: context.schemas.database.tables,\n }\n : null,\n api: context.schemas.api ? { type: context.schemas.api.type } : null,\n env: context.schemas.env\n ? { variableCount: context.schemas.env.variables.length }\n : null,\n models: context.schemas.models?.map((m) => m.path) || [],\n },\n skills: context.skills.map((s) => ({\n name: s.frontmatter.name,\n description: s.frontmatter.description,\n source: s.source,\n })),\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `Project analysis:\\n\\n${formatTechStack(context.techStack)}\\n\\n${JSON.stringify(info, null, 2)}`,\n },\n ],\n }\n }\n\n case \"agentx_skill_match\": {\n const task = args.task as string\n const skills = await loadLocalSkills(cwd)\n const matches = matchSkillsToTask(skills, task)\n\n if (!matches.length) {\n return {\n content: [\n {\n type: \"text\",\n text: \"No matching skills found. Install skills with: agentx skill install <owner/repo>\",\n },\n ],\n }\n }\n\n const text = matches\n .map(\n (m) =>\n `- **${m.skill.frontmatter.name}** (relevance: ${(m.relevance * 100).toFixed(0)}%)\\n ${m.skill.frontmatter.description}\\n Match: ${m.matchReason}`\n )\n .join(\"\\n\\n\")\n\n return {\n content: [{ type: \"text\", text: `Matching skills:\\n\\n${text}` }],\n }\n }\n\n case \"agentx_detect_output_type\": {\n const task = args.task as string\n const type = resolveOutputType(undefined, task)\n return {\n content: [\n {\n type: \"text\",\n text: `Detected output type: ${type}`,\n },\n ],\n }\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`)\n }\n}\n\n// --- Stdio transport ---\n\nexport async function startMcpServer(): Promise<void> {\n // Use stderr for logging (stdout is reserved for JSON-RPC)\n const log = (...args: unknown[]) => console.error(\"[agentx-mcp]\", ...args)\n\n log(\"Starting MCP server (stdio transport)...\")\n\n let buffer = \"\"\n\n process.stdin.setEncoding(\"utf8\")\n process.stdin.on(\"data\", (chunk: string) => {\n buffer += chunk\n\n // Process complete messages (Content-Length header based)\n while (true) {\n const headerEnd = buffer.indexOf(\"\\r\\n\\r\\n\")\n if (headerEnd === -1) break\n\n const header = buffer.slice(0, headerEnd)\n const contentLengthMatch = header.match(/Content-Length:\\s*(\\d+)/)\n if (!contentLengthMatch) {\n // Try without header (some clients send raw JSON)\n const newlineIdx = buffer.indexOf(\"\\n\")\n if (newlineIdx === -1) break\n\n const line = buffer.slice(0, newlineIdx).trim()\n buffer = buffer.slice(newlineIdx + 1)\n\n if (line) {\n try {\n const msg = JSON.parse(line)\n handleMessage(msg, log).catch((e) => log(\"Error:\", e))\n } catch {\n // Not valid JSON, skip\n }\n }\n continue\n }\n\n const contentLength = parseInt(contentLengthMatch[1], 10)\n const bodyStart = headerEnd + 4\n const bodyEnd = bodyStart + contentLength\n\n if (buffer.length < bodyEnd) break // Need more data\n\n const body = buffer.slice(bodyStart, bodyEnd)\n buffer = buffer.slice(bodyEnd)\n\n try {\n const msg = JSON.parse(body)\n handleMessage(msg, log).catch((e) => log(\"Error:\", e))\n } catch (e) {\n log(\"Failed to parse message:\", e)\n }\n }\n })\n\n process.stdin.on(\"end\", () => {\n log(\"stdin closed, shutting down.\")\n process.exit(0)\n })\n}\n\nfunction send(message: JsonRpcResponse | JsonRpcNotification): void {\n const body = JSON.stringify(message)\n const header = `Content-Length: ${Buffer.byteLength(body)}\\r\\n\\r\\n`\n process.stdout.write(header + body)\n}\n\nasync function handleMessage(\n msg: JsonRpcRequest,\n log: (...args: unknown[]) => void\n): Promise<void> {\n const { method, id, params } = msg\n\n log(`Received: ${method}`)\n\n switch (method) {\n case \"initialize\": {\n send({\n jsonrpc: \"2.0\",\n id,\n result: {\n protocolVersion: PROTOCOL_VERSION,\n capabilities: CAPABILITIES,\n serverInfo: SERVER_INFO,\n },\n })\n break\n }\n\n case \"notifications/initialized\": {\n log(\"Client initialized.\")\n break\n }\n\n case \"tools/list\": {\n send({\n jsonrpc: \"2.0\",\n id,\n result: { tools: TOOLS },\n })\n break\n }\n\n case \"tools/call\": {\n const toolName = (params as any)?.name as string\n const toolArgs = ((params as any)?.arguments || {}) as Record<string, unknown>\n\n try {\n const result = await handleToolCall(toolName, toolArgs)\n send({\n jsonrpc: \"2.0\",\n id,\n result,\n })\n } catch (error: any) {\n send({\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [{ type: \"text\", text: `Error: ${error.message}` }],\n isError: true,\n },\n })\n }\n break\n }\n\n case \"ping\": {\n send({ jsonrpc: \"2.0\", id, result: {} })\n break\n }\n\n default: {\n if (id !== undefined) {\n send({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32601, message: `Method not found: ${method}` },\n })\n }\n }\n }\n}\n","import { execa } from \"execa\"\nimport type { GitStatus, GitLogEntry, GitDiffFile, GitCommitResult } from \"./types\"\n\n// --- Git Manager: wraps git operations via execa ---\n\nexport class GitManager {\n constructor(private cwd: string) {}\n\n /**\n * Check if the current directory is a git repository.\n */\n async isRepo(): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd: this.cwd,\n reject: false,\n })\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get current git status.\n */\n async status(): Promise<GitStatus> {\n const result = await execa(\"git\", [\"status\", \"--porcelain\", \"-b\"], {\n cwd: this.cwd,\n reject: false,\n })\n\n const lines = result.stdout.trim().split(\"\\n\").filter(Boolean)\n let branch = \"unknown\"\n const staged: string[] = []\n const modified: string[] = []\n const untracked: string[] = []\n const deleted: string[] = []\n\n for (const line of lines) {\n // Branch line: ## main...origin/main\n if (line.startsWith(\"## \")) {\n branch = line.slice(3).split(\"...\")[0]\n continue\n }\n\n const indexStatus = line[0]\n const workStatus = line[1]\n const file = line.slice(3).trim()\n\n // Staged changes (index column)\n if (indexStatus === \"A\" || indexStatus === \"M\" || indexStatus === \"R\") {\n staged.push(file)\n }\n if (indexStatus === \"D\") {\n deleted.push(file)\n staged.push(file)\n }\n\n // Unstaged changes (working tree column)\n if (workStatus === \"M\") {\n modified.push(file)\n }\n if (workStatus === \"D\") {\n deleted.push(file)\n }\n\n // Untracked\n if (indexStatus === \"?\" && workStatus === \"?\") {\n untracked.push(file)\n }\n }\n\n return {\n staged,\n modified,\n untracked,\n deleted: [...new Set(deleted)],\n branch,\n isClean: staged.length === 0 && modified.length === 0 && untracked.length === 0,\n }\n }\n\n /**\n * Get git diff (staged or unstaged).\n */\n async diff(staged = false): Promise<string> {\n const args = staged ? [\"diff\", \"--cached\"] : [\"diff\"]\n const result = await execa(\"git\", args, {\n cwd: this.cwd,\n reject: false,\n })\n return result.stdout\n }\n\n /**\n * Get diff summary with file-level stats.\n */\n async diffStat(staged = false): Promise<GitDiffFile[]> {\n const args = staged\n ? [\"diff\", \"--cached\", \"--numstat\"]\n : [\"diff\", \"--numstat\"]\n\n const result = await execa(\"git\", args, {\n cwd: this.cwd,\n reject: false,\n })\n\n const files: GitDiffFile[] = []\n for (const line of result.stdout.trim().split(\"\\n\").filter(Boolean)) {\n const [additions, deletions, path] = line.split(\"\\t\")\n if (!path) continue\n\n let status: GitDiffFile[\"status\"] = \"modified\"\n if (additions === \"-\" && deletions === \"-\") {\n status = \"renamed\" // binary or renamed\n }\n\n files.push({\n path,\n status,\n additions: parseInt(additions) || 0,\n deletions: parseInt(deletions) || 0,\n })\n }\n\n return files\n }\n\n /**\n * Get recent git log entries.\n */\n async log(count = 10): Promise<GitLogEntry[]> {\n const result = await execa(\n \"git\",\n [\"log\", `--max-count=${count}`, \"--format=%H|%h|%s|%an|%ai\"],\n {\n cwd: this.cwd,\n reject: false,\n }\n )\n\n if (!result.stdout.trim()) return []\n\n return result.stdout\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => {\n const [hash, shortHash, message, author, date] = line.split(\"|\")\n return { hash, shortHash, message, author, date }\n })\n }\n\n /**\n * Stage files.\n */\n async add(files: string[]): Promise<void> {\n if (!files.length) return\n await execa(\"git\", [\"add\", ...files], { cwd: this.cwd })\n }\n\n /**\n * Stage all changes.\n */\n async addAll(): Promise<void> {\n await execa(\"git\", [\"add\", \"-A\"], { cwd: this.cwd })\n }\n\n /**\n * Commit with a message.\n */\n async commit(message: string): Promise<GitCommitResult> {\n const result = await execa(\"git\", [\"commit\", \"-m\", message], {\n cwd: this.cwd,\n reject: false,\n })\n\n if (result.exitCode !== 0) {\n throw new Error(result.stderr || result.stdout || \"Git commit failed\")\n }\n\n // Parse commit hash from output\n const hashMatch = result.stdout.match(/\\[[\\w/.-]+\\s+(\\w+)\\]/)\n const hash = hashMatch?.[1] || \"unknown\"\n\n // Count files changed\n const filesMatch = result.stdout.match(/(\\d+)\\s+files?\\s+changed/)\n const filesChanged = parseInt(filesMatch?.[1] || \"0\")\n\n return { hash, message, filesChanged }\n }\n\n /**\n * Get current branch name.\n */\n async currentBranch(): Promise<string> {\n const result = await execa(\"git\", [\"branch\", \"--show-current\"], {\n cwd: this.cwd,\n reject: false,\n })\n return result.stdout.trim()\n }\n\n /**\n * Create and switch to a new branch.\n */\n async createBranch(name: string): Promise<void> {\n await execa(\"git\", [\"checkout\", \"-b\", name], { cwd: this.cwd })\n }\n\n /**\n * Switch to an existing branch.\n */\n async checkout(name: string): Promise<void> {\n await execa(\"git\", [\"checkout\", name], { cwd: this.cwd })\n }\n\n /**\n * Stash current changes.\n */\n async stash(message?: string): Promise<void> {\n const args = [\"stash\", \"push\"]\n if (message) args.push(\"-m\", message)\n await execa(\"git\", args, { cwd: this.cwd })\n }\n\n /**\n * Pop the latest stash.\n */\n async stashPop(): Promise<void> {\n await execa(\"git\", [\"stash\", \"pop\"], { cwd: this.cwd })\n }\n\n /**\n * Generate an AI commit message from staged changes.\n * Returns a conventional commit message based on the diff.\n */\n async generateCommitMessage(provider?: {\n generate: (messages: any[], options?: any) => Promise<any>\n }): Promise<string> {\n const diff = await this.diff(true)\n if (!diff.trim()) {\n throw new Error(\"No staged changes to commit\")\n }\n\n if (!provider) {\n // Fallback: generate from diff summary\n return this.fallbackCommitMessage(diff)\n }\n\n const result = await provider.generate([\n {\n role: \"system\",\n content: `You are a git commit message generator. Generate a conventional commit message (type(scope): subject) from the given diff.\nRules:\n- Use conventional commit format: feat|fix|refactor|docs|test|chore|style(scope): message\n- Keep the subject line under 72 characters\n- Be specific about what changed\n- Output ONLY the commit message, nothing else`,\n },\n {\n role: \"user\",\n content: `Generate a commit message for this diff:\\n\\n${diff.slice(0, 4000)}`,\n },\n ])\n\n return result.content.trim().split(\"\\n\")[0]\n }\n\n private fallbackCommitMessage(diff: string): string {\n const lines = diff.split(\"\\n\")\n const fileChanges: string[] = []\n\n for (const line of lines) {\n if (line.startsWith(\"diff --git\")) {\n const match = line.match(/b\\/(.+)$/)\n if (match) fileChanges.push(match[1])\n }\n }\n\n if (fileChanges.length === 0) return \"chore: update files\"\n if (fileChanges.length === 1) return `chore: update ${fileChanges[0]}`\n return `chore: update ${fileChanges.length} files`\n }\n}\n","import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from \"fs\"\nimport path from \"path\"\nimport os from \"os\"\nimport type { GenerationMessage } from \"@/agent/providers/types\"\n\n// --- Session management for REPL persistence ---\n\nexport interface Session {\n id: string\n createdAt: string\n updatedAt: string\n cwd: string\n messages: GenerationMessage[]\n tokensUsed: number\n filesGenerated: string[]\n}\n\nconst SESSIONS_DIR = path.join(os.homedir(), \".agentx\", \"sessions\")\n\nfunction ensureSessionsDir(): void {\n if (!existsSync(SESSIONS_DIR)) {\n mkdirSync(SESSIONS_DIR, { recursive: true })\n }\n}\n\n/**\n * Create a new session.\n */\nexport function createSession(cwd: string): Session {\n const id = generateId()\n return {\n id,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n cwd,\n messages: [],\n tokensUsed: 0,\n filesGenerated: [],\n }\n}\n\n/**\n * Save a session to disk.\n */\nexport function saveSession(session: Session): void {\n ensureSessionsDir()\n const filePath = path.join(SESSIONS_DIR, `${session.id}.json`)\n session.updatedAt = new Date().toISOString()\n writeFileSync(filePath, JSON.stringify(session, null, 2), \"utf8\")\n}\n\n/**\n * Load a session from disk.\n */\nexport function loadSession(id: string): Session | null {\n const filePath = path.join(SESSIONS_DIR, `${id}.json`)\n if (!existsSync(filePath)) return null\n try {\n return JSON.parse(readFileSync(filePath, \"utf8\")) as Session\n } catch {\n return null\n }\n}\n\n/**\n * Load the most recent session.\n */\nexport function loadLatestSession(): Session | null {\n ensureSessionsDir()\n const files = readdirSync(SESSIONS_DIR)\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => ({\n name: f,\n path: path.join(SESSIONS_DIR, f),\n }))\n\n if (!files.length) return null\n\n // Sort by modification time, most recent first\n let latest: { name: string; session: Session } | null = null\n for (const file of files) {\n try {\n const session = JSON.parse(readFileSync(file.path, \"utf8\")) as Session\n if (!latest || session.updatedAt > latest.session.updatedAt) {\n latest = { name: file.name, session }\n }\n } catch {\n // Skip corrupted files\n }\n }\n\n return latest?.session ?? null\n}\n\n/**\n * List all saved sessions.\n */\nexport function listSessions(): Session[] {\n ensureSessionsDir()\n const files = readdirSync(SESSIONS_DIR).filter((f) => f.endsWith(\".json\"))\n const sessions: Session[] = []\n\n for (const file of files) {\n try {\n const session = JSON.parse(\n readFileSync(path.join(SESSIONS_DIR, file), \"utf8\")\n ) as Session\n sessions.push(session)\n } catch {\n // Skip corrupted files\n }\n }\n\n // Sort by most recent first\n sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))\n return sessions\n}\n\nfunction generateId(): string {\n return Math.random().toString(36).slice(2, 10) + Date.now().toString(36).slice(-4)\n}\n","import chalk from \"chalk\"\nimport { writeFileSync } from \"fs\"\nimport path from \"path\"\nimport type { Session } from \"./session\"\nimport { saveSession, loadSession, loadLatestSession, listSessions } from \"./session\"\nimport { renderHelp, renderCost, renderCostBreakdown, renderGitStatus } from \"./renderer\"\nimport { GitManager } from \"@/git\"\nimport { createProvider } from \"@/agent/providers\"\nimport { logger } from \"@/utils/logger\"\nimport { globalTracker, exportSession } from \"@/observability\"\nimport { MemoryHierarchy } from \"@/memory\"\nimport { globalPermissions, PERMISSION_MODES, type PermissionMode } from \"@/permissions\"\nimport prompts from \"prompts\"\n\n// --- REPL slash commands ---\n\nexport interface CommandContext {\n session: Session\n cwd: string\n onSessionChange: (session: Session) => void\n}\n\nexport type SlashCommandHandler = (\n args: string,\n ctx: CommandContext\n) => Promise<boolean> // Returns true to continue REPL, false to quit\n\nconst commands: Record<string, SlashCommandHandler> = {}\n\nexport function registerCommand(name: string, handler: SlashCommandHandler): void {\n commands[name] = handler\n}\n\nexport function getCommand(name: string): SlashCommandHandler | undefined {\n return commands[name]\n}\n\nexport function isCommand(input: string): boolean {\n return input.startsWith(\"/\")\n}\n\nexport function parseCommand(input: string): { name: string; args: string } {\n const trimmed = input.trim()\n const spaceIdx = trimmed.indexOf(\" \")\n if (spaceIdx === -1) {\n return { name: trimmed.slice(1), args: \"\" }\n }\n return {\n name: trimmed.slice(1, spaceIdx),\n args: trimmed.slice(spaceIdx + 1).trim(),\n }\n}\n\n// --- Built-in commands ---\n\nregisterCommand(\"help\", async () => {\n renderHelp()\n return true\n})\n\nregisterCommand(\"quit\", async () => {\n return false\n})\n\nregisterCommand(\"exit\", async () => {\n return false\n})\n\nregisterCommand(\"q\", async () => {\n return false\n})\n\nregisterCommand(\"clear\", async (_args, ctx) => {\n ctx.session.messages = []\n console.log(chalk.dim(\" Conversation cleared\"))\n return true\n})\n\nregisterCommand(\"save\", async (_args, ctx) => {\n saveSession(ctx.session)\n console.log(chalk.dim(` Session saved: ${ctx.session.id}`))\n return true\n})\n\nregisterCommand(\"load\", async (args, ctx) => {\n let session: Session | null = null\n\n if (args) {\n session = loadSession(args)\n if (!session) {\n logger.warn(`Session not found: ${args}`)\n return true\n }\n } else {\n // Show session list and let user pick\n const sessions = listSessions()\n if (!sessions.length) {\n logger.info(\"No saved sessions\")\n return true\n }\n\n const { sessionId } = await prompts({\n type: \"select\",\n name: \"sessionId\",\n message: \"Select a session\",\n choices: sessions.slice(0, 10).map((s) => ({\n title: `${s.id} — ${new Date(s.updatedAt).toLocaleDateString()} (${s.messages.length} messages)`,\n value: s.id,\n })),\n })\n\n if (!sessionId) return true\n session = loadSession(sessionId)\n }\n\n if (session) {\n ctx.onSessionChange(session)\n console.log(\n chalk.dim(` Loaded session: ${session.id} (${session.messages.length} messages)`)\n )\n }\n\n return true\n})\n\nregisterCommand(\"undo\", async (_args, ctx) => {\n // Remove last assistant + user message pair\n const messages = ctx.session.messages\n if (messages.length < 2) {\n logger.info(\"Nothing to undo\")\n return true\n }\n\n // Pop from the end: assistant response, then user prompt\n if (messages[messages.length - 1]?.role === \"assistant\") {\n messages.pop()\n }\n if (messages[messages.length - 1]?.role === \"user\") {\n messages.pop()\n }\n\n console.log(chalk.dim(\" Undid last exchange\"))\n return true\n})\n\nregisterCommand(\"cost\", async (_args, ctx) => {\n const summary = globalTracker.getSummary()\n if (summary.steps.length > 0) {\n renderCostBreakdown(summary)\n } else {\n renderCost(ctx.session.tokensUsed)\n }\n return true\n})\n\nregisterCommand(\"export\", async (args, ctx) => {\n const summary = globalTracker.getSummary()\n const markdown = exportSession(ctx.session, summary.steps.length ? summary : undefined)\n const filename = args || `session-${ctx.session.id}.md`\n const filePath = path.resolve(ctx.cwd, filename)\n writeFileSync(filePath, markdown, \"utf8\")\n logger.success(` Session exported to ${filePath}`)\n return true\n})\n\nregisterCommand(\"files\", async (_args, ctx) => {\n const files = ctx.session.filesGenerated\n if (!files.length) {\n logger.info(\"No files generated in this session\")\n return true\n }\n\n console.log()\n console.log(chalk.dim(` Files generated (${files.length}):`))\n for (const f of files) {\n console.log(` ${chalk.green(\"+\")} ${f}`)\n }\n console.log()\n return true\n})\n\nregisterCommand(\"context\", async (_args, ctx) => {\n console.log()\n console.log(chalk.dim(` Session: ${ctx.session.id}`))\n console.log(chalk.dim(` CWD: ${ctx.session.cwd}`))\n console.log(chalk.dim(` Messages: ${ctx.session.messages.length}`))\n console.log(chalk.dim(` Tokens: ${ctx.session.tokensUsed.toLocaleString()}`))\n console.log(chalk.dim(` Files: ${ctx.session.filesGenerated.length}`))\n console.log(chalk.dim(` Created: ${new Date(ctx.session.createdAt).toLocaleString()}`))\n console.log()\n return true\n})\n\n// --- Memory commands ---\n\nregisterCommand(\"memory\", async (_args, ctx) => {\n try {\n const memory = new MemoryHierarchy(ctx.cwd)\n await memory.load()\n\n const stats = memory.getStats()\n const prefs = memory.getPreferences()\n const patterns = memory.getPatterns()\n const recent = memory.getRecentGenerations(5)\n\n console.log()\n console.log(chalk.bold(\" Memory\"))\n console.log()\n console.log(chalk.dim(\" Project:\"))\n console.log(chalk.dim(` Generations: ${stats.project.totalGenerations}`))\n console.log(chalk.dim(` Success rate: ${(stats.project.successRate * 100).toFixed(0)}%`))\n console.log(chalk.dim(` Heals: ${stats.project.totalHeals}`))\n console.log()\n console.log(chalk.dim(\" Global:\"))\n console.log(chalk.dim(` Generations: ${stats.user.totalGenerations}`))\n console.log(chalk.dim(` Success rate: ${(stats.user.successRate * 100).toFixed(0)}%`))\n\n if (prefs.length) {\n console.log()\n console.log(chalk.dim(\" Preferences:\"))\n for (const p of prefs.slice(0, 10)) {\n console.log(chalk.dim(` ${p.key}: ${p.value} (${(p.confidence * 100).toFixed(0)}%)`))\n }\n }\n\n if (patterns.length) {\n console.log()\n console.log(chalk.dim(\" Patterns:\"))\n for (const p of patterns.slice(0, 5)) {\n console.log(chalk.dim(` ${p.description} (${p.frequency}x)`))\n }\n }\n\n if (recent.length) {\n console.log()\n console.log(chalk.dim(\" Recent:\"))\n for (const r of recent) {\n const status = r.success ? chalk.green(\"ok\") : chalk.red(\"fail\")\n console.log(chalk.dim(` [${status}] ${r.task.slice(0, 60)}`))\n }\n }\n\n console.log()\n } catch (error: any) {\n logger.error(` ${error.message}`)\n }\n return true\n})\n\n// --- Permission commands ---\n\nregisterCommand(\"mode\", async (args, _ctx) => {\n if (args && PERMISSION_MODES.includes(args as PermissionMode)) {\n globalPermissions.setMode(args as PermissionMode)\n logger.success(` Permission mode: ${args}`)\n } else if (args) {\n logger.warn(` Unknown mode: ${args}. Valid modes: ${PERMISSION_MODES.join(\", \")}`)\n } else {\n const current = globalPermissions.getMode()\n console.log()\n console.log(chalk.dim(` Current mode: ${chalk.bold(current)}`))\n console.log()\n console.log(chalk.dim(\" Available modes:\"))\n console.log(chalk.dim(\" default — confirm each file write\"))\n console.log(chalk.dim(\" acceptEdits — auto-allow writes, confirm destructive ops\"))\n console.log(chalk.dim(\" plan — show plan without writing\"))\n console.log(chalk.dim(\" yolo — auto-allow everything\"))\n console.log()\n console.log(chalk.dim(` Usage: /mode <mode>`))\n console.log()\n }\n return true\n})\n\n// --- Git commands ---\n\nregisterCommand(\"commit\", async (_args, ctx) => {\n try {\n const gm = new GitManager(ctx.cwd)\n if (!(await gm.isRepo())) {\n logger.warn(\"Not a git repository\")\n return true\n }\n\n // Auto-stage generated files\n const generatedFiles = ctx.session.filesGenerated.filter((f) => f)\n if (generatedFiles.length) {\n await gm.add(generatedFiles)\n console.log(chalk.dim(` Staged ${generatedFiles.length} generated file(s)`))\n }\n\n const status = await gm.status()\n if (status.staged.length === 0) {\n logger.warn(\"Nothing staged to commit\")\n return true\n }\n\n // Generate AI commit message\n let message: string\n try {\n const provider = createProvider()\n message = await gm.generateCommitMessage(provider)\n } catch {\n message = await gm.generateCommitMessage()\n }\n\n console.log(chalk.dim(` Message: ${message}`))\n\n const result = await gm.commit(message)\n logger.success(` [${result.hash}] ${result.message}`)\n } catch (error: any) {\n logger.error(` ${error.message}`)\n }\n\n return true\n})\n\nregisterCommand(\"diff\", async (_args, ctx) => {\n try {\n const gm = new GitManager(ctx.cwd)\n const diff = await gm.diff()\n if (!diff.trim()) {\n logger.info(\"No changes\")\n } else {\n console.log(diff)\n }\n } catch (error: any) {\n logger.error(` ${error.message}`)\n }\n return true\n})\n\nregisterCommand(\"status\", async (_args, ctx) => {\n try {\n const gm = new GitManager(ctx.cwd)\n if (!(await gm.isRepo())) {\n logger.warn(\"Not a git repository\")\n return true\n }\n const status = await gm.status()\n renderGitStatus(status)\n } catch (error: any) {\n logger.error(` ${error.message}`)\n }\n return true\n})\n","import chalk from \"chalk\"\nimport type { WriteResult } from \"@/agent/outputs/handlers\"\nimport type { UsageSummary } from \"@/observability\"\n\n// --- Terminal rendering utilities for the REPL ---\n\n/**\n * Render the REPL welcome banner.\n */\nexport function renderBanner(version: string, sessionId: string): void {\n console.log()\n console.log(chalk.bold.cyan(\" agentx\") + chalk.dim(` v${version}`))\n console.log(chalk.dim(` Session: ${sessionId}`))\n console.log(chalk.dim(\" Type /help for commands, /quit to exit\"))\n console.log()\n}\n\n/**\n * Render file write results.\n */\nexport function renderFiles(result: WriteResult): void {\n if (result.written.length) {\n console.log()\n console.log(chalk.green(` Created ${result.written.length} file(s):`))\n for (const file of result.written) {\n console.log(` ${chalk.green(\"+\")} ${file}`)\n }\n }\n\n if (result.skipped.length) {\n console.log()\n console.log(chalk.yellow(` Skipped ${result.skipped.length} file(s):`))\n for (const file of result.skipped) {\n console.log(` ${chalk.yellow(\"~\")} ${file}`)\n }\n }\n\n if (result.errors.length) {\n console.log()\n console.log(chalk.red(` Failed ${result.errors.length} file(s):`))\n for (const err of result.errors) {\n console.log(` ${chalk.red(\"x\")} ${err}`)\n }\n }\n}\n\n/**\n * Render token usage and cost estimate.\n */\nexport function renderCost(tokensUsed: number): void {\n // Rough cost estimate based on Sonnet pricing ($3/MTok input, $15/MTok output)\n // We only have total tokens, so use a blended rate of ~$9/MTok\n const cost = (tokensUsed / 1_000_000) * 9\n console.log()\n console.log(\n chalk.dim(` Tokens: ${tokensUsed.toLocaleString()} | Est. cost: $${cost.toFixed(4)}`)\n )\n}\n\n/**\n * Render AI response text with basic formatting.\n */\nexport function renderResponse(content: string): void {\n if (!content.trim()) return\n console.log()\n\n // Simple rendering: preserve code blocks, add indentation\n const lines = content.split(\"\\n\")\n let inCodeBlock = false\n\n for (const line of lines) {\n if (line.startsWith(\"```\")) {\n inCodeBlock = !inCodeBlock\n console.log(chalk.dim(` ${line}`))\n continue\n }\n\n if (inCodeBlock) {\n console.log(chalk.dim(` ${line}`))\n } else {\n console.log(` ${line}`)\n }\n }\n}\n\n/**\n * Render a streaming text chunk (no newline).\n */\nexport function renderStreamChunk(text: string): void {\n process.stdout.write(text)\n}\n\n/**\n * Render help text for REPL commands.\n */\nexport function renderHelp(): void {\n console.log()\n console.log(chalk.bold(\" Commands:\"))\n console.log()\n console.log(` ${chalk.cyan(\"/help\")} Show this help`)\n console.log(` ${chalk.cyan(\"/clear\")} Clear conversation history`)\n console.log(` ${chalk.cyan(\"/save\")} Save current session`)\n console.log(` ${chalk.cyan(\"/load\")} Load a saved session`)\n console.log(` ${chalk.cyan(\"/undo\")} Undo last generation`)\n console.log(` ${chalk.cyan(\"/cost\")} Show token usage and cost breakdown`)\n console.log(` ${chalk.cyan(\"/export\")} Export session as markdown`)\n console.log(` ${chalk.cyan(\"/files\")} List generated files`)\n console.log(` ${chalk.cyan(\"/context\")} Show session context info`)\n console.log(` ${chalk.cyan(\"/memory\")} Show memory stats and preferences`)\n console.log(` ${chalk.cyan(\"/mode\")} Switch permission mode`)\n console.log(` ${chalk.cyan(\"/commit\")} Commit generated files with AI message`)\n console.log(` ${chalk.cyan(\"/diff\")} Show git diff`)\n console.log(` ${chalk.cyan(\"/status\")} Show git status`)\n console.log(` ${chalk.cyan(\"/quit\")} Exit the REPL`)\n console.log()\n}\n\n/**\n * Render a git status summary.\n */\nexport function renderGitStatus(status: {\n branch: string\n staged: string[]\n modified: string[]\n untracked: string[]\n isClean: boolean\n}): void {\n console.log()\n console.log(chalk.dim(` Branch: ${status.branch}`))\n\n if (status.isClean) {\n console.log(chalk.green(\" Working tree clean\"))\n return\n }\n\n if (status.staged.length) {\n console.log(chalk.green(` Staged: ${status.staged.length}`))\n }\n if (status.modified.length) {\n console.log(chalk.yellow(` Modified: ${status.modified.length}`))\n }\n if (status.untracked.length) {\n console.log(chalk.dim(` Untracked: ${status.untracked.length}`))\n }\n console.log()\n}\n\n/**\n * Render detailed cost breakdown with per-step and per-model info.\n */\nexport function renderCostBreakdown(summary: UsageSummary): void {\n console.log()\n console.log(chalk.bold(\" Cost Breakdown\"))\n console.log()\n console.log(\n chalk.dim(\n ` Total: ${summary.totalTokens.toLocaleString()} tokens ($${summary.totalCost.toFixed(4)})`\n )\n )\n console.log(\n chalk.dim(\n ` Input: ${summary.totalInputTokens.toLocaleString()} | Output: ${summary.totalOutputTokens.toLocaleString()}`\n )\n )\n\n if (Object.keys(summary.models).length) {\n console.log()\n console.log(chalk.dim(\" Per model:\"))\n for (const [model, usage] of Object.entries(summary.models)) {\n console.log(\n ` ${chalk.cyan(model)}: ${(usage.inputTokens + usage.outputTokens).toLocaleString()} tokens, $${usage.cost.toFixed(4)} (${usage.steps} step${usage.steps !== 1 ? \"s\" : \"\"})`\n )\n }\n }\n\n if (summary.steps.length > 1) {\n console.log()\n console.log(chalk.dim(\" Per step:\"))\n for (const step of summary.steps) {\n console.log(\n ` Step ${step.step}: ${(step.inputTokens + step.outputTokens).toLocaleString()} tokens ($${step.cost.toFixed(4)})`\n )\n }\n }\n console.log()\n}\n\n/**\n * Render a plan preview showing what files would be written (for plan mode).\n */\nexport function renderPlan(files: Array<{ path: string; action: string }>): void {\n console.log()\n console.log(chalk.bold(\" Plan Preview\"))\n console.log(chalk.dim(\" No files will be written in plan mode.\"))\n console.log()\n for (const file of files) {\n const icon = file.action === \"create\" ? chalk.green(\"+\") : chalk.yellow(\"~\")\n console.log(` ${icon} ${file.path} (${file.action})`)\n }\n console.log()\n}\n","import { createInterface, type Interface } from \"readline\"\nimport chalk from \"chalk\"\nimport ora from \"ora\"\nimport type { Session } from \"./session\"\nimport { createSession, saveSession, loadSession, loadLatestSession } from \"./session\"\nimport { isCommand, parseCommand, getCommand, type CommandContext } from \"./commands\"\nimport { renderBanner, renderResponse, renderFiles, renderCost, renderPlan, renderStreamChunk } from \"./renderer\"\nimport { generateStream, type GenerateOptions, type GenerateStreamEvent } from \"@/agent\"\nimport type { GenerationMessage } from \"@/agent/providers/types\"\nimport { logger } from \"@/utils/logger\"\nimport { globalPermissions } from \"@/permissions\"\n\n// --- REPL Engine ---\n\nexport interface ReplOptions {\n cwd: string\n provider?: string\n model?: string\n apiKey?: string\n resume?: boolean\n sessionId?: string\n version: string\n}\n\nexport class ReplEngine {\n private rl: Interface | null = null\n private session: Session\n private options: ReplOptions\n private running = false\n\n constructor(options: ReplOptions) {\n this.options = options\n\n // Resume or create session\n if (options.sessionId) {\n const loaded = loadSession(options.sessionId)\n if (!loaded) {\n logger.warn(`Session ${options.sessionId} not found, starting new session`)\n this.session = createSession(options.cwd)\n } else {\n this.session = loaded\n }\n } else if (options.resume) {\n const latest = loadLatestSession()\n if (!latest) {\n logger.info(\"No previous session found, starting new session\")\n this.session = createSession(options.cwd)\n } else {\n this.session = latest\n logger.info(`Resumed session: ${latest.id}`)\n }\n } else {\n this.session = createSession(options.cwd)\n }\n }\n\n /**\n * Start the REPL loop.\n */\n async start(): Promise<void> {\n this.running = true\n renderBanner(this.options.version, this.session.id)\n\n // Show resumed session context\n if (this.session.messages.length > 0) {\n console.log(\n chalk.dim(\n ` Resumed with ${this.session.messages.length} messages, ${this.session.tokensUsed.toLocaleString()} tokens`\n )\n )\n console.log()\n }\n\n this.rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: chalk.cyan(\"agentx > \"),\n terminal: true,\n })\n\n this.rl.prompt()\n\n this.rl.on(\"line\", async (line) => {\n const input = line.trim()\n\n if (!input) {\n this.rl?.prompt()\n return\n }\n\n try {\n if (isCommand(input)) {\n const shouldContinue = await this.handleCommand(input)\n if (!shouldContinue) {\n this.stop()\n return\n }\n } else {\n await this.handleGeneration(input)\n }\n } catch (error: any) {\n logger.error(` Error: ${error.message}`)\n }\n\n if (this.running) {\n this.rl?.prompt()\n }\n })\n\n this.rl.on(\"close\", () => {\n this.stop()\n })\n\n // Handle Ctrl+C gracefully\n this.rl.on(\"SIGINT\", () => {\n console.log()\n this.stop()\n })\n }\n\n /**\n * Stop the REPL and save session.\n */\n private stop(): void {\n this.running = false\n saveSession(this.session)\n console.log()\n console.log(chalk.dim(` Session saved: ${this.session.id}`))\n renderCost(this.session.tokensUsed)\n console.log()\n this.rl?.close()\n process.exit(0)\n }\n\n /**\n * Handle a slash command.\n */\n private async handleCommand(input: string): Promise<boolean> {\n const { name, args } = parseCommand(input)\n const handler = getCommand(name)\n\n if (!handler) {\n logger.warn(` Unknown command: /${name}. Type /help for available commands.`)\n return true\n }\n\n const ctx: CommandContext = {\n session: this.session,\n cwd: this.options.cwd,\n onSessionChange: (newSession) => {\n this.session = newSession\n },\n }\n\n return handler(args, ctx)\n }\n\n /**\n * Handle a natural language generation prompt.\n * Uses streaming to render text in real-time instead of blocking with a spinner.\n */\n private async handleGeneration(input: string): Promise<void> {\n const spinner = ora({\n text: \"Thinking...\",\n color: \"cyan\",\n }).start()\n\n try {\n // Build session messages for multi-turn context (exclude system messages)\n const sessionMessages: GenerationMessage[] = this.session.messages\n .filter((m) => m.role !== \"system\")\n .map((m) => ({ role: m.role, content: m.content }))\n\n const generateOptions: GenerateOptions = {\n task: input,\n cwd: this.options.cwd,\n provider: (this.options.provider as any) || \"claude-code\",\n model: this.options.model,\n apiKey: this.options.apiKey,\n overwrite: true,\n dryRun: false,\n interactive: false,\n context7: true,\n sessionMessages,\n }\n\n let result: import(\"@/agent\").GenerateResult | undefined\n let streaming = false\n\n for await (const event of generateStream(generateOptions)) {\n if (event.type === \"context_ready\") {\n spinner.stop()\n console.log()\n streaming = true\n continue\n }\n if (event.type === \"text_delta\") {\n renderStreamChunk(event.text)\n continue\n }\n if (event.type === \"done\") {\n console.log()\n continue\n }\n if (event.type === \"error\") {\n throw new Error(event.error)\n }\n if (event.type === \"step_complete\") {\n if (event.step > 1) {\n console.log(chalk.dim(` Step ${event.step}: ${event.filesCount} file(s)`))\n }\n continue\n }\n if (event.type === \"generate_result\") {\n result = event.result\n }\n }\n\n // Ensure spinner is stopped if streaming never started\n if (!streaming) {\n spinner.stop()\n }\n\n if (!result) return\n\n // Render file results (plan mode shows preview instead)\n if (result.files.written.length || result.files.skipped.length || result.files.errors.length) {\n if (globalPermissions.getMode() === \"plan\") {\n renderPlan(result.files.written.map((f) => ({ path: f, action: \"create\" })))\n } else {\n renderFiles(result.files)\n }\n }\n\n // Track cost\n if (result.tokensUsed) {\n renderCost(result.tokensUsed)\n }\n\n // Update session\n this.session.messages.push({ role: \"user\", content: input })\n this.session.messages.push({\n role: \"assistant\",\n content: result.content || \"\",\n })\n this.session.tokensUsed += result.tokensUsed || 0\n this.session.filesGenerated.push(...result.files.written)\n\n // Handle follow-up questions\n if (result.followUp) {\n console.log()\n console.log(chalk.yellow(` ${result.followUp}`))\n }\n\n // Display heal results if present\n if (result.healResult) {\n console.log()\n if (result.healResult.healed) {\n console.log(chalk.green(` Heal: passed verification${result.healResult.attempts > 0 ? ` (fixed in ${result.healResult.attempts} attempt(s))` : \"\"}`))\n } else if (result.healResult.error) {\n console.log(chalk.red(` Heal: verification failed after ${result.healResult.attempts} attempt(s)`))\n console.log(chalk.dim(` ${result.healResult.error.split(\"\\n\")[0]}`))\n }\n }\n } catch (error: any) {\n spinner.stop()\n throw error\n }\n }\n}\n","// --- A2A Protocol Server ---\n\nimport { createServer, type IncomingMessage, type ServerResponse } from \"http\"\nimport { generate, generateStream } from \"@/agent\"\nimport type { ProviderName } from \"@/agent/providers\"\nimport type {\n AgentCard,\n Task,\n TaskState,\n TaskMessage,\n TaskArtifact,\n TaskStatusUpdate,\n JsonRpcRequest,\n JsonRpcResponse,\n JsonRpcError,\n MessagePart,\n} from \"./types\"\nimport { A2A_ERRORS } from \"./types\"\n\nexport interface A2AServerConfig {\n port: number\n host: string\n provider: ProviderName\n model?: string\n apiKey?: string\n cwd: string\n cors: boolean\n}\n\nconst DEFAULT_CONFIG: A2AServerConfig = {\n port: 3171,\n host: \"0.0.0.0\",\n provider: \"claude-code\",\n cwd: process.cwd(),\n cors: true,\n}\n\nexport class A2AServer {\n private config: A2AServerConfig\n private tasks: Map<string, Task> = new Map()\n private activeCancellations: Set<string> = new Set()\n private log: (...args: unknown[]) => void\n\n constructor(config?: Partial<A2AServerConfig>) {\n this.config = { ...DEFAULT_CONFIG, ...config }\n this.log = console.error.bind(console, \"[a2a]\")\n }\n\n async start(): Promise<void> {\n const server = createServer(async (req, res) => {\n if (this.config.cors) {\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\")\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\")\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\")\n if (req.method === \"OPTIONS\") {\n res.writeHead(204)\n res.end()\n return\n }\n }\n\n await this.handleRequest(req, res)\n })\n\n server.listen(this.config.port, this.config.host, () => {\n this.log(`\\n agentx A2A server v0.1.0`)\n this.log(` Listening on http://${this.config.host}:${this.config.port}`)\n this.log(` Provider: ${this.config.provider}`)\n this.log(` Working dir: ${this.config.cwd}`)\n this.log(\"\")\n this.log(\" Discovery:\")\n this.log(` GET /.well-known/agent-card.json`)\n this.log(\"\")\n this.log(\" JSON-RPC 2.0 methods:\")\n this.log(\" tasks/send — synchronous task execution\")\n this.log(\" tasks/sendSubscribe — streaming task execution (SSE)\")\n this.log(\" tasks/get — retrieve task state\")\n this.log(\" tasks/cancel — cancel running task\")\n this.log(\"\")\n })\n }\n\n private getAgentCard(): AgentCard {\n return {\n name: \"agentx\",\n description:\n \"AI-powered agentic code generation agent. Generates components, pages, APIs, documents, skills, and more for any tech stack.\",\n url: `http://${this.config.host}:${this.config.port}`,\n version: \"0.1.0\",\n capabilities: {\n streaming: true,\n pushNotifications: false,\n stateTransitionHistory: true,\n },\n skills: [\n {\n id: \"generate\",\n name: \"Code Generation\",\n description:\n \"Generate code files from natural language descriptions. Supports components, pages, APIs, tests, schemas, and more.\",\n tags: [\"code-generation\", \"ai\", \"multi-framework\"],\n examples: [\n \"Create a React login form with email and password validation\",\n \"Generate a REST API for user management with CRUD operations\",\n \"Build a dashboard page with charts and data tables\",\n ],\n },\n {\n id: \"evolve\",\n name: \"Code Transformation\",\n description:\n \"Transform existing code files based on natural language instructions. Applies targeted edits with diff preview.\",\n tags: [\"code-transformation\", \"refactoring\", \"ai\"],\n examples: [\n \"Add dark mode support to this component\",\n \"Refactor this API to use async/await instead of callbacks\",\n ],\n },\n {\n id: \"inspect\",\n name: \"Project Analysis\",\n description:\n \"Analyze a project's tech stack, schemas, dependencies, and structure.\",\n tags: [\"analysis\", \"project-inspection\"],\n examples: [\n \"What tech stack does this project use?\",\n \"List all API schemas in the project\",\n ],\n },\n ],\n defaultInputModes: [\"text\"],\n defaultOutputModes: [\"text\", \"file\"],\n }\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url || \"/\", `http://${req.headers.host || \"localhost\"}`)\n const method = req.method || \"GET\"\n const pathname = url.pathname\n\n this.log(`${method} ${pathname}`)\n\n try {\n // Agent card discovery\n if (method === \"GET\" && pathname === \"/.well-known/agent-card.json\") {\n this.sendJson(res, 200, this.getAgentCard())\n return\n }\n\n // JSON-RPC 2.0 endpoint\n if (method === \"POST\" && pathname === \"/\") {\n const body = await readBody(req)\n await this.handleJsonRpc(body, res)\n return\n }\n\n this.sendJson(res, 404, {\n error: \"Not found\",\n hint: \"Use GET /.well-known/agent-card.json for discovery or POST / for JSON-RPC\",\n })\n } catch (error: any) {\n this.log(\"Error:\", error.message)\n this.sendJson(res, 500, { error: error.message })\n }\n }\n\n private async handleJsonRpc(\n request: Record<string, unknown>,\n res: ServerResponse\n ): Promise<void> {\n // Validate JSON-RPC format\n if (request.jsonrpc !== \"2.0\" || !request.method || !request.id) {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: (request.id as string | number) || 0,\n error: A2A_ERRORS.PARSE_ERROR,\n })\n return\n }\n\n const rpc = request as unknown as JsonRpcRequest\n const params = (rpc.params || {}) as Record<string, unknown>\n\n switch (rpc.method) {\n case \"tasks/send\":\n await this.handleTaskSend(rpc.id, params, res)\n break\n case \"tasks/sendSubscribe\":\n await this.handleTaskSendSubscribe(rpc.id, params, res)\n break\n case \"tasks/get\":\n this.handleTaskGet(rpc.id, params, res)\n break\n case \"tasks/cancel\":\n this.handleTaskCancel(rpc.id, params, res)\n break\n default:\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpc.id,\n error: A2A_ERRORS.METHOD_NOT_FOUND,\n })\n }\n }\n\n private async handleTaskSend(\n rpcId: string | number,\n params: Record<string, unknown>,\n res: ServerResponse\n ): Promise<void> {\n const taskId = String(params.id || `task-${Date.now().toString(36)}`)\n const message = params.message as { role?: string; parts?: MessagePart[] } | undefined\n\n if (!message?.parts?.length) {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n error: { ...A2A_ERRORS.INVALID_PARAMS, data: \"message with parts is required\" },\n })\n return\n }\n\n // Extract text from message parts\n const textParts = message.parts.filter((p) => p.type === \"text\") as Array<{ type: \"text\"; text: string }>\n const taskText = textParts.map((p) => p.text).join(\"\\n\")\n\n if (!taskText) {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n error: { ...A2A_ERRORS.INVALID_PARAMS, data: \"No text content in message parts\" },\n })\n return\n }\n\n // Create task\n const task: Task = {\n id: taskId,\n state: \"submitted\",\n messages: [{ role: \"user\", parts: message.parts as MessagePart[] }],\n artifacts: [],\n metadata: params.metadata as Record<string, unknown> | undefined,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n this.tasks.set(taskId, task)\n\n // Execute generation\n task.state = \"working\"\n task.updatedAt = new Date().toISOString()\n\n try {\n const result = await generate({\n task: taskText,\n cwd: this.config.cwd,\n provider: this.config.provider,\n model: this.config.model,\n apiKey: this.config.apiKey,\n overwrite: true,\n interactive: false,\n context7: true,\n })\n\n // Build artifacts from generated files\n const artifacts: TaskArtifact[] = result.files.written.map((filePath, i) => ({\n name: filePath,\n description: `Generated file`,\n parts: [{ type: \"text\" as const, text: filePath }],\n index: i,\n }))\n\n // Add agent response message\n const agentMessage: TaskMessage = {\n role: \"agent\",\n parts: [{ type: \"text\", text: result.content || \"Generation complete.\" }],\n }\n\n if (result.followUp) {\n task.state = \"input-required\"\n agentMessage.parts.push({\n type: \"text\",\n text: `\\n\\nQuestion: ${result.followUp}`,\n })\n } else {\n task.state = \"completed\"\n }\n\n task.messages.push(agentMessage)\n task.artifacts = artifacts\n task.updatedAt = new Date().toISOString()\n } catch (error: any) {\n task.state = \"failed\"\n task.messages.push({\n role: \"agent\",\n parts: [{ type: \"text\", text: `Error: ${error.message}` }],\n })\n task.updatedAt = new Date().toISOString()\n }\n\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n result: task,\n })\n }\n\n private async handleTaskSendSubscribe(\n rpcId: string | number,\n params: Record<string, unknown>,\n res: ServerResponse\n ): Promise<void> {\n const taskId = String(params.id || `task-${Date.now().toString(36)}`)\n const message = params.message as { role?: string; parts?: MessagePart[] } | undefined\n\n if (!message?.parts?.length) {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n error: { ...A2A_ERRORS.INVALID_PARAMS, data: \"message with parts is required\" },\n })\n return\n }\n\n const textParts = message.parts.filter((p) => p.type === \"text\") as Array<{ type: \"text\"; text: string }>\n const taskText = textParts.map((p) => p.text).join(\"\\n\")\n\n if (!taskText) {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n error: { ...A2A_ERRORS.INVALID_PARAMS, data: \"No text content in message parts\" },\n })\n return\n }\n\n // Set up SSE headers\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n \"Connection\": \"keep-alive\",\n })\n\n // Create task\n const task: Task = {\n id: taskId,\n state: \"submitted\",\n messages: [{ role: \"user\", parts: message.parts as MessagePart[] }],\n artifacts: [],\n metadata: params.metadata as Record<string, unknown> | undefined,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n this.tasks.set(taskId, task)\n\n const sendSSE = (update: TaskStatusUpdate) => {\n res.write(`data: ${JSON.stringify(update)}\\n\\n`)\n }\n\n // Send initial submitted event\n sendSSE({\n id: taskId,\n state: \"submitted\",\n final: false,\n })\n\n // Start working\n task.state = \"working\"\n task.updatedAt = new Date().toISOString()\n\n sendSSE({\n id: taskId,\n state: \"working\",\n final: false,\n })\n\n try {\n let textContent = \"\"\n const artifacts: TaskArtifact[] = []\n\n for await (const event of generateStream({\n task: taskText,\n cwd: this.config.cwd,\n provider: this.config.provider,\n model: this.config.model,\n apiKey: this.config.apiKey,\n overwrite: true,\n interactive: false,\n context7: true,\n })) {\n // Check cancellation\n if (this.activeCancellations.has(taskId)) {\n this.activeCancellations.delete(taskId)\n task.state = \"canceled\"\n task.updatedAt = new Date().toISOString()\n sendSSE({ id: taskId, state: \"canceled\", final: true })\n res.end()\n return\n }\n\n if (event.type === \"text_delta\") {\n textContent += event.text\n sendSSE({\n id: taskId,\n state: \"working\",\n message: {\n role: \"agent\",\n parts: [{ type: \"text\", text: event.text }],\n },\n final: false,\n })\n }\n\n if (event.type === \"generate_result\") {\n const result = event.result\n const fileArtifacts = result.files.written.map((filePath, i) => ({\n name: filePath,\n parts: [{ type: \"text\" as const, text: filePath }],\n index: i,\n }))\n artifacts.push(...fileArtifacts)\n\n for (const artifact of fileArtifacts) {\n sendSSE({\n id: taskId,\n state: \"working\",\n artifact,\n final: false,\n })\n }\n\n if (result.followUp) {\n task.state = \"input-required\"\n } else {\n task.state = \"completed\"\n }\n }\n }\n\n task.messages.push({\n role: \"agent\",\n parts: [{ type: \"text\", text: textContent || \"Generation complete.\" }],\n })\n task.artifacts = artifacts\n task.updatedAt = new Date().toISOString()\n\n sendSSE({\n id: taskId,\n state: task.state,\n final: true,\n })\n } catch (error: any) {\n task.state = \"failed\"\n task.messages.push({\n role: \"agent\",\n parts: [{ type: \"text\", text: `Error: ${error.message}` }],\n })\n task.updatedAt = new Date().toISOString()\n\n sendSSE({\n id: taskId,\n state: \"failed\",\n message: {\n role: \"agent\",\n parts: [{ type: \"text\", text: `Error: ${error.message}` }],\n },\n final: true,\n })\n }\n\n res.end()\n }\n\n private handleTaskGet(\n rpcId: string | number,\n params: Record<string, unknown>,\n res: ServerResponse\n ): void {\n const taskId = String(params.id || \"\")\n const task = this.tasks.get(taskId)\n\n if (!task) {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n error: A2A_ERRORS.TASK_NOT_FOUND,\n })\n return\n }\n\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n result: task,\n })\n }\n\n private handleTaskCancel(\n rpcId: string | number,\n params: Record<string, unknown>,\n res: ServerResponse\n ): void {\n const taskId = String(params.id || \"\")\n const task = this.tasks.get(taskId)\n\n if (!task) {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n error: A2A_ERRORS.TASK_NOT_FOUND,\n })\n return\n }\n\n if (task.state !== \"working\" && task.state !== \"submitted\") {\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n error: A2A_ERRORS.TASK_NOT_CANCELABLE,\n })\n return\n }\n\n this.activeCancellations.add(taskId)\n task.state = \"canceled\"\n task.updatedAt = new Date().toISOString()\n\n this.sendJsonRpc(res, {\n jsonrpc: \"2.0\",\n id: rpcId,\n result: task,\n })\n }\n\n private sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" })\n res.end(JSON.stringify(data, null, 2))\n }\n\n private sendJsonRpc(res: ServerResponse, response: JsonRpcResponse): void {\n if (!res.headersSent) {\n res.writeHead(200, { \"Content-Type\": \"application/json\" })\n }\n res.end(JSON.stringify(response))\n }\n}\n\nasync function readBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let body = \"\"\n req.on(\"data\", (chunk) => (body += chunk))\n req.on(\"end\", () => {\n try {\n resolve(body ? JSON.parse(body) : {})\n } catch {\n resolve({})\n }\n })\n req.on(\"error\", reject)\n })\n}\n","// --- A2A Protocol types per Google A2A spec ---\n\n// Agent capability advertisement\nexport interface AgentCard {\n name: string\n description: string\n url: string\n version: string\n capabilities: {\n streaming: boolean\n pushNotifications: boolean\n stateTransitionHistory: boolean\n }\n skills: AgentSkill[]\n defaultInputModes: string[]\n defaultOutputModes: string[]\n}\n\nexport interface AgentSkill {\n id: string\n name: string\n description: string\n tags: string[]\n examples?: string[]\n}\n\n// Task state machine\nexport type TaskState =\n | \"submitted\"\n | \"working\"\n | \"input-required\"\n | \"completed\"\n | \"failed\"\n | \"canceled\"\n\nexport interface Task {\n id: string\n state: TaskState\n messages: TaskMessage[]\n artifacts: TaskArtifact[]\n metadata?: Record<string, unknown>\n createdAt: string\n updatedAt: string\n}\n\nexport interface TaskMessage {\n role: \"user\" | \"agent\"\n parts: MessagePart[]\n}\n\nexport type MessagePart =\n | TextPart\n | FilePart\n | DataPart\n\nexport interface TextPart {\n type: \"text\"\n text: string\n}\n\nexport interface FilePart {\n type: \"file\"\n file: {\n name: string\n mimeType?: string\n bytes?: string // base64 encoded\n uri?: string\n }\n}\n\nexport interface DataPart {\n type: \"data\"\n data: Record<string, unknown>\n}\n\n// Generated outputs\nexport interface TaskArtifact {\n name: string\n description?: string\n parts: MessagePart[]\n index: number\n}\n\n// SSE event format\nexport interface TaskStatusUpdate {\n id: string\n state: TaskState\n message?: TaskMessage\n artifact?: TaskArtifact\n final: boolean\n metadata?: Record<string, unknown>\n}\n\n// JSON-RPC 2.0 types\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\"\n id: string | number\n method: string\n params?: Record<string, unknown>\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: \"2.0\"\n id: string | number\n result?: unknown\n error?: JsonRpcError\n}\n\nexport interface JsonRpcError {\n code: number\n message: string\n data?: unknown\n}\n\n// A2A-specific error codes\nexport const A2A_ERRORS = {\n TASK_NOT_FOUND: { code: -32001, message: \"Task not found\" },\n TASK_NOT_CANCELABLE: { code: -32002, message: \"Task cannot be canceled\" },\n INVALID_PARAMS: { code: -32602, message: \"Invalid params\" },\n INTERNAL_ERROR: { code: -32603, message: \"Internal error\" },\n METHOD_NOT_FOUND: { code: -32601, message: \"Method not found\" },\n PARSE_ERROR: { code: -32700, message: \"Parse error\" },\n} as const\n","import type { AgentCard, Task, MessagePart, JsonRpcResponse } from \"./types\"\n\n// --- A2A Client: call remote agents via A2A protocol ---\n\nexport class A2AClient {\n private baseUrl: string\n private token?: string\n\n constructor(baseUrl: string, token?: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, \"\")\n this.token = token\n }\n\n /**\n * Fetch the remote agent's card.\n */\n async getAgentCard(): Promise<AgentCard> {\n const res = await fetch(`${this.baseUrl}/.well-known/agent-card.json`, {\n headers: this.headers(),\n })\n if (!res.ok) throw new Error(`Failed to fetch agent card: ${res.status}`)\n return res.json() as Promise<AgentCard>\n }\n\n /**\n * Send a task synchronously and wait for completion.\n */\n async sendTask(\n text: string,\n metadata?: Record<string, unknown>,\n ): Promise<Task> {\n const response = await this.rpc(\"tasks/send\", {\n id: `task-${Date.now().toString(36)}`,\n message: {\n role: \"user\",\n parts: [{ type: \"text\", text }] as MessagePart[],\n },\n metadata,\n })\n\n if (response.error) {\n throw new Error(`A2A error: ${response.error.message}`)\n }\n\n return response.result as Task\n }\n\n /**\n * Send a task with SSE streaming.\n */\n async *sendTaskStream(\n text: string,\n metadata?: Record<string, unknown>,\n ): AsyncIterable<{ state: string; message?: string; final: boolean }> {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"tasks/sendSubscribe\",\n params: {\n id: `task-${Date.now().toString(36)}`,\n message: {\n role: \"user\",\n parts: [{ type: \"text\", text }],\n },\n metadata,\n },\n })\n\n const res = await fetch(this.baseUrl, {\n method: \"POST\",\n headers: {\n ...this.headers(),\n \"Content-Type\": \"application/json\",\n \"Accept\": \"text/event-stream\",\n },\n body,\n })\n\n if (!res.ok || !res.body) {\n throw new Error(`A2A stream error: ${res.status}`)\n }\n\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buffer = \"\"\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split(\"\\n\")\n buffer = lines.pop() || \"\"\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const data = JSON.parse(line.slice(6))\n yield {\n state: data.state,\n message: data.message?.parts?.[0]?.text,\n final: data.final,\n }\n } catch {\n // Skip malformed events\n }\n }\n }\n }\n }\n\n /**\n * Get task status by ID.\n */\n async getTask(taskId: string): Promise<Task> {\n const response = await this.rpc(\"tasks/get\", { id: taskId })\n if (response.error) {\n throw new Error(`A2A error: ${response.error.message}`)\n }\n return response.result as Task\n }\n\n /**\n * Cancel a running task.\n */\n async cancelTask(taskId: string): Promise<Task> {\n const response = await this.rpc(\"tasks/cancel\", { id: taskId })\n if (response.error) {\n throw new Error(`A2A error: ${response.error.message}`)\n }\n return response.result as Task\n }\n\n private async rpc(method: string, params: Record<string, unknown>): Promise<JsonRpcResponse> {\n const res = await fetch(this.baseUrl, {\n method: \"POST\",\n headers: {\n ...this.headers(),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: Date.now(),\n method,\n params,\n }),\n })\n\n if (!res.ok) {\n throw new Error(`A2A HTTP error: ${res.status}`)\n }\n\n return res.json() as Promise<JsonRpcResponse>\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = {}\n if (this.token) {\n h[\"Authorization\"] = `Bearer ${this.token}`\n }\n return h\n }\n}\n","import type { MeshPeer, DaemonConfig } from \"@/daemon/config\"\nimport type { AgentCard, AgentSkill } from \"./types\"\nimport { A2AClient } from \"./client\"\n\n// --- A2A Mesh: peer discovery, health checks, agent directory ---\n\nexport interface PeerState {\n peer: MeshPeer\n client: A2AClient\n healthy: boolean\n lastCheck?: Date\n agentCard?: AgentCard\n agents: AgentSkill[]\n}\n\nexport class A2AMesh {\n private peers: Map<string, PeerState> = new Map()\n private healthTimer?: ReturnType<typeof setInterval>\n private config: DaemonConfig\n private log: (...args: unknown[]) => void\n\n constructor(\n config: DaemonConfig,\n log: (...args: unknown[]) => void = console.error.bind(console, \"[mesh]\"),\n ) {\n this.config = config\n this.log = log\n\n for (const peer of config.mesh.peers) {\n this.peers.set(peer.name, {\n peer,\n client: new A2AClient(peer.url, peer.token),\n healthy: false,\n agents: [],\n })\n }\n }\n\n /**\n * Start the mesh: discover peers and begin health checks.\n */\n async start(): Promise<void> {\n this.log(`Mesh starting with ${this.peers.size} peer(s)`)\n\n // Initial discovery\n await this.discoverAll()\n\n // Periodic health checks\n const interval = this.config.mesh.healthCheck.interval * 1000\n this.healthTimer = setInterval(() => this.discoverAll(), interval)\n }\n\n async stop(): Promise<void> {\n if (this.healthTimer) {\n clearInterval(this.healthTimer)\n }\n }\n\n /**\n * Discover agent cards from all peers.\n */\n async discoverAll(): Promise<void> {\n const results = await Promise.allSettled(\n Array.from(this.peers.entries()).map(([name, state]) =>\n this.discoverPeer(name, state),\n ),\n )\n\n const healthy = Array.from(this.peers.values()).filter((p) => p.healthy).length\n this.log(`Discovery complete: ${healthy}/${this.peers.size} peers healthy`)\n }\n\n private async discoverPeer(name: string, state: PeerState): Promise<void> {\n const timeout = this.config.mesh.healthCheck.timeout * 1000\n\n try {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeout)\n\n const card = await state.client.getAgentCard()\n clearTimeout(timer)\n\n state.healthy = true\n state.lastCheck = new Date()\n state.agentCard = card\n state.agents = card.skills || []\n\n this.log(`Peer \"${name}\" healthy: ${card.name} (${state.agents.length} skills)`)\n } catch (e: any) {\n state.healthy = false\n state.lastCheck = new Date()\n this.log(`Peer \"${name}\" unreachable: ${e.message}`)\n }\n }\n\n /**\n * Send a task to a remote peer by name.\n * Uses the peer's /task HTTP endpoint (agentx daemon API).\n * If no agent specified, uses the first available agent on the peer.\n */\n async sendTask(peerName: string, text: string, agentId?: string): Promise<string> {\n const state = this.peers.get(peerName)\n if (!state) throw new Error(`Unknown peer: ${peerName}`)\n if (!state.healthy) throw new Error(`Peer \"${peerName}\" is not healthy`)\n\n // Default to first agent on the peer\n const agent = agentId || state.agents[0]?.id\n if (!agent) throw new Error(`Peer \"${peerName}\" has no agents`)\n\n const url = `${state.peer.url}/task`\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" }\n if (state.peer.token) {\n headers[\"Authorization\"] = `Bearer ${state.peer.token}`\n }\n\n const res = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ agent, message: text }),\n })\n\n if (!res.ok) {\n throw new Error(`Peer \"${peerName}\" /task error: ${res.status}`)\n }\n\n const data = await res.json() as { content?: string; error?: string }\n if (data.error) throw new Error(`Peer \"${peerName}\" agent error: ${data.error}`)\n return data.content || \"No response\"\n }\n\n /**\n * Find a peer that has a specific skill.\n */\n findPeerWithSkill(skillId: string): PeerState | undefined {\n for (const state of this.peers.values()) {\n if (state.healthy && state.agents.some((a) => a.id === skillId)) {\n return state\n }\n }\n return undefined\n }\n\n /**\n * Get the combined agent directory across all healthy peers.\n */\n directory(): Array<{\n peer: string\n peerUrl: string\n healthy: boolean\n skills: AgentSkill[]\n lastCheck?: Date\n }> {\n return Array.from(this.peers.entries()).map(([name, state]) => ({\n peer: name,\n peerUrl: state.peer.url,\n healthy: state.healthy,\n skills: state.agents,\n lastCheck: state.lastCheck,\n }))\n }\n}\n","import { z } from \"zod\"\nimport { readFileSync, existsSync } from \"fs\"\nimport { resolve } from \"path\"\n\n/**\n * Load .env file into process.env (simple, no dependency).\n */\nfunction loadDotEnv(dir: string): void {\n const envPath = resolve(dir, \".env\")\n if (!existsSync(envPath)) return\n\n const content = readFileSync(envPath, \"utf-8\")\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith(\"#\")) continue\n const eqIdx = trimmed.indexOf(\"=\")\n if (eqIdx === -1) continue\n const key = trimmed.slice(0, eqIdx).trim()\n const value = trimmed.slice(eqIdx + 1).trim()\n if (!process.env[key]) {\n process.env[key] = value\n }\n }\n}\n\n// --- Daemon configuration schema & loader ---\n\nconst providerConfigSchema = z.object({\n apiKey: z.string().optional(),\n defaultModel: z.string().optional(),\n baseUrl: z.string().optional(),\n})\n\nconst agentConfigSchema = z.object({\n name: z.string(),\n workspace: z.string(),\n tier: z.enum([\"claude-code\", \"sdk\", \"orchestrator\"]).default(\"claude-code\"),\n provider: z.string().optional(),\n model: z.string().optional(),\n systemPrompt: z.string().optional(),\n mentions: z.array(z.string()).default([]),\n maxConcurrent: z.number().default(1),\n permissionMode: z.string().default(\"default\"),\n})\n\nconst telegramAccountSchema = z.object({\n token: z.string(),\n agentBinding: z.string(),\n})\n\nconst channelsConfigSchema = z.object({\n telegram: z.object({\n enabled: z.boolean().default(false),\n accounts: z.record(z.string(), telegramAccountSchema).default({}),\n policy: z.object({\n dm: z.enum([\"pair\", \"block\"]).default(\"pair\"),\n group: z.enum([\"mention-required\", \"all\"]).default(\"mention-required\"),\n }).default({}),\n }).default({}),\n whatsapp: z.object({\n enabled: z.boolean().default(false),\n sessionDir: z.string().default(\".agentx/whatsapp-sessions\"),\n agentBinding: z.string().optional(),\n }).default({}),\n})\n\nconst cronJobSchema = z.object({\n enabled: z.boolean().default(true),\n schedule: z.string(),\n timezone: z.string().default(\"UTC\"),\n agent: z.string(),\n prompt: z.string(),\n timeout: z.number().default(600),\n model: z.string().optional(),\n onError: z.enum([\"log\", \"notify\", \"disable\"]).default(\"log\"),\n})\n\nconst meshPeerSchema = z.object({\n url: z.string(),\n name: z.string(),\n token: z.string().optional(),\n})\n\nconst meshConfigSchema = z.object({\n enabled: z.boolean().default(false),\n peers: z.array(meshPeerSchema).default([]),\n discovery: z.enum([\"static\", \"mdns\"]).default(\"static\"),\n healthCheck: z.object({\n interval: z.number().default(60),\n timeout: z.number().default(10),\n }).default({}),\n})\n\nexport const daemonConfigSchema = z.object({\n node: z.object({\n id: z.string(),\n name: z.string(),\n bind: z.string().default(\"127.0.0.1:18800\"),\n }),\n providers: z.record(z.string(), providerConfigSchema).default({}),\n agents: z.record(z.string(), agentConfigSchema).default({}),\n channels: channelsConfigSchema.default({}),\n crons: z.record(z.string(), cronJobSchema).default({}),\n mesh: meshConfigSchema.default({}),\n})\n\nexport type DaemonConfig = z.infer<typeof daemonConfigSchema>\nexport type AgentDef = z.infer<typeof agentConfigSchema>\nexport type CronJobDef = z.infer<typeof cronJobSchema>\nexport type MeshPeer = z.infer<typeof meshPeerSchema>\n\n/**\n * Expand environment variables in strings: ${VAR_NAME} -> process.env.VAR_NAME\n */\nfunction expandEnvVars(obj: unknown): unknown {\n if (typeof obj === \"string\") {\n return obj.replace(/\\$\\{(\\w+)\\}/g, (_match, name) => process.env[name] || \"\")\n }\n if (Array.isArray(obj)) {\n return obj.map(expandEnvVars)\n }\n if (obj !== null && typeof obj === \"object\") {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n result[key] = expandEnvVars(value)\n }\n return result\n }\n return obj\n}\n\n/**\n * Load daemon config from agentx.json, with env var expansion and validation.\n */\nexport function loadDaemonConfig(configPath?: string): DaemonConfig {\n const paths = configPath\n ? [configPath]\n : [\n resolve(process.cwd(), \"agentx.json\"),\n resolve(process.cwd(), \".agentx/config.json\"),\n ]\n\n // Load .env from same directory as config search\n loadDotEnv(process.cwd())\n\n let raw: string | undefined\n let foundPath: string | undefined\n\n for (const p of paths) {\n if (existsSync(p)) {\n raw = readFileSync(p, \"utf-8\")\n foundPath = p\n break\n }\n }\n\n if (!raw || !foundPath) {\n throw new Error(\n `No config found. Create agentx.json or .agentx/config.json\\n` +\n `Searched: ${paths.join(\", \")}`\n )\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (e: any) {\n throw new Error(`Invalid JSON in ${foundPath}: ${e.message}`)\n }\n\n // Expand environment variables\n const expanded = expandEnvVars(parsed)\n\n // Validate\n const result = daemonConfigSchema.safeParse(expanded)\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` ${i.path.join(\".\")}: ${i.message}`)\n .join(\"\\n\")\n throw new Error(`Config validation failed (${foundPath}):\\n${issues}`)\n }\n\n return result.data\n}\n\n/**\n * Validate agent workspace directories exist and have .claude/ setup.\n */\nexport function validateWorkspaces(config: DaemonConfig): string[] {\n const warnings: string[] = []\n\n for (const [id, agent] of Object.entries(config.agents)) {\n if (!existsSync(agent.workspace)) {\n warnings.push(`Agent \"${id}\": workspace not found at ${agent.workspace}`)\n continue\n }\n\n if (agent.tier === \"claude-code\") {\n const claudeDir = resolve(agent.workspace, \".claude\")\n if (!existsSync(claudeDir)) {\n warnings.push(\n `Agent \"${id}\": no .claude/ directory in workspace ${agent.workspace}. ` +\n `Claude Code native features (hooks, MCP, skills) won't be available.`\n )\n }\n }\n\n // Check provider availability\n const providerName = agent.provider || \"claude\"\n const providerConfig = config.providers[providerName]\n if (agent.tier !== \"claude-code\" && (!providerConfig || !providerConfig.apiKey)) {\n warnings.push(\n `Agent \"${id}\": provider \"${providerName}\" has no API key configured. ` +\n `Set providers.${providerName}.apiKey in config or use tier \"claude-code\" for subscription.`\n )\n }\n }\n\n // Validate cron agent bindings\n for (const [id, cron] of Object.entries(config.crons)) {\n if (!config.agents[cron.agent]) {\n warnings.push(`Cron \"${id}\": references unknown agent \"${cron.agent}\"`)\n }\n }\n\n // Validate channel agent bindings\n if (config.channels.telegram.enabled) {\n for (const [name, account] of Object.entries(config.channels.telegram.accounts)) {\n if (!config.agents[account.agentBinding]) {\n warnings.push(\n `Telegram account \"${name}\": references unknown agent \"${account.agentBinding}\"`\n )\n }\n }\n }\n\n return warnings\n}\n","import { execa } from \"execa\"\nimport { execFile, spawn } from \"child_process\"\nimport type { AgentDef } from \"@/daemon/config\"\n\n// --- Agent execution runtime ---\n// Routes agent tasks to the correct execution tier:\n// - claude-code: spawns claude CLI (subscription, full features)\n// - sdk: uses Claude Agent SDK (API key, programmatic)\n// - orchestrator: uses agentx's own agentic loop (any provider)\n\nexport interface AgentPeer {\n id: string\n name: string\n handle?: string // e.g. \"@noqta_devops_bot\"\n role?: string // from systemPrompt, first line\n}\n\nexport interface AgentTask {\n message: string\n agentId: string\n context?: {\n channel?: string\n sender?: string\n group?: string\n conversationHistory?: Array<{ role: string; content: string }>\n /** This agent's own handle on the current channel */\n myHandle?: string\n /** Other available agents and their handles */\n peers?: AgentPeer[]\n }\n}\n\nexport interface AgentResponse {\n content: string\n error?: string\n tokensUsed?: number\n duration?: number\n claudeSessionId?: string // Captured from Claude Code for session resumption\n}\n\n/** Callback for streaming text deltas */\nexport type StreamCallback = (delta: string, fullText: string) => void\n\n/**\n * Build the prompt from agent config + task context + conversation history.\n */\nfunction buildPrompt(agent: AgentDef, task: AgentTask, historyContext?: string): string {\n const parts: string[] = []\n\n if (agent.systemPrompt) {\n parts.push(agent.systemPrompt)\n }\n\n // Inject environment context so the agent knows where it is and who else is available\n if (task.context) {\n const ctx = task.context\n const envLines: string[] = [\"\", \"[Environment]\"]\n\n if (ctx.channel) envLines.push(`Channel: ${ctx.channel}`)\n if (ctx.group) envLines.push(`Group: ${ctx.group}`)\n if (ctx.sender) envLines.push(`Message from: ${ctx.sender}`)\n if (ctx.myHandle) envLines.push(`Your handle on this channel: ${ctx.myHandle}`)\n\n if (ctx.peers?.length) {\n envLines.push(\"\")\n envLines.push(\"[Team — other agents you can mention to delegate or collaborate]\")\n for (const peer of ctx.peers) {\n const handle = peer.handle ? ` (mention: ${peer.handle})` : \"\"\n const role = peer.role ? ` — ${peer.role}` : \"\"\n envLines.push(`• ${peer.name}${handle}${role}`)\n }\n envLines.push(\"\")\n envLines.push(\"To involve another agent, mention their handle in your response and they will automatically see it and reply.\")\n }\n\n parts.push(envLines.join(\"\\n\"))\n }\n\n // Inject conversation history for session continuity\n if (historyContext) {\n parts.push(\"\")\n parts.push(historyContext)\n }\n\n parts.push(\"\")\n parts.push(task.message)\n\n return parts.join(\"\\n\")\n}\n\n/**\n * Build CLI args for claude command.\n */\nfunction buildClaudeArgs(\n agent: AgentDef,\n prompt: string,\n streaming: boolean,\n resumeSessionId?: string,\n): string[] {\n const args: string[] = [\n \"-p\", prompt,\n \"--output-format\", streaming ? \"stream-json\" : \"text\",\n ]\n\n // Resume existing Claude session for conversation continuity\n if (resumeSessionId) {\n args.push(\"--resume\", resumeSessionId)\n }\n\n if (agent.model) {\n args.push(\"--model\", agent.model)\n }\n\n if (agent.permissionMode === \"bypassPermissions\") {\n args.push(\"--dangerously-skip-permissions\")\n }\n\n return args\n}\n\n/**\n * Extract Claude session ID from CLI output.\n * Claude Code prints session info in stderr when using --verbose.\n */\nfunction extractSessionId(stderr: string): string | undefined {\n // Claude Code outputs: \"Session: <id>\" or similar in verbose mode\n // Also check for session ID in the output format\n const match = stderr.match(/session[:\\s]+([a-f0-9-]{36})/i)\n || stderr.match(/sessionId[:\\s]+\"?([a-f0-9-]{36})\"?/i)\n return match?.[1]\n}\n\n/**\n * Execute a task using the Claude Code CLI (tier: \"claude-code\").\n * Non-streaming — waits for full response.\n */\nexport async function executeClaudeCode(\n agent: AgentDef,\n task: AgentTask,\n historyContext?: string,\n resumeSessionId?: string,\n): Promise<AgentResponse> {\n const start = Date.now()\n const prompt = buildPrompt(agent, task, resumeSessionId ? undefined : historyContext)\n const args = buildClaudeArgs(agent, prompt, false, resumeSessionId)\n\n try {\n const { stdout, stderr } = await new Promise<{ stdout: string; stderr: string }>((resolve, reject) => {\n execFile(\"claude\", args, {\n cwd: agent.workspace,\n timeout: 600_000,\n maxBuffer: 10 * 1024 * 1024, // 10MB\n env: process.env,\n }, (error, stdout, stderr) => {\n if (error && !stdout) {\n reject(error)\n } else {\n resolve({ stdout: stdout || \"\", stderr: stderr || \"\" })\n }\n })\n })\n\n const capturedSessionId = extractSessionId(stderr)\n\n return {\n content: stdout,\n duration: Date.now() - start,\n claudeSessionId: capturedSessionId,\n }\n } catch (error: any) {\n return {\n content: \"\",\n error: error.message || \"Claude Code failed\",\n duration: Date.now() - start,\n }\n }\n}\n\n/**\n * Execute with streaming — calls onDelta with text chunks as they arrive.\n * Uses claude --output-format stream-json to get real-time output.\n */\nexport async function executeClaudeCodeStreaming(\n agent: AgentDef,\n task: AgentTask,\n onDelta: StreamCallback,\n historyContext?: string,\n resumeSessionId?: string,\n): Promise<AgentResponse> {\n const start = Date.now()\n const prompt = buildPrompt(agent, task, resumeSessionId ? undefined : historyContext)\n const args = buildClaudeArgs(agent, prompt, true, resumeSessionId)\n\n let fullText = \"\"\n\n try {\n const proc = execa(\"claude\", args, {\n cwd: agent.workspace,\n timeout: 600_000, // 10 minutes\n reject: false,\n env: process.env,\n // Don't buffer — we'll read stdout line by line\n buffer: false,\n })\n\n // Parse stream-json output line by line\n if (proc.stdout) {\n let lineBuffer = \"\"\n\n proc.stdout.on(\"data\", (chunk: Buffer) => {\n lineBuffer += chunk.toString()\n const lines = lineBuffer.split(\"\\n\")\n lineBuffer = lines.pop() || \"\"\n\n for (const line of lines) {\n if (!line.trim()) continue\n try {\n const event = JSON.parse(line)\n\n // Claude stream-json emits different event types\n // \"assistant\" messages with content contain the text\n if (event.type === \"assistant\" && event.message?.content) {\n for (const block of event.message.content) {\n if (block.type === \"text\" && block.text) {\n const delta = block.text.slice(fullText.length)\n if (delta) {\n fullText = block.text\n onDelta(delta, fullText)\n }\n }\n }\n }\n\n // \"content_block_delta\" for streaming text\n if (event.type === \"content_block_delta\" && event.delta?.text) {\n fullText += event.delta.text\n onDelta(event.delta.text, fullText)\n }\n\n // \"result\" event contains final text\n if (event.type === \"result\" && event.result) {\n const resultText = typeof event.result === \"string\"\n ? event.result\n : event.result\n if (typeof resultText === \"string\" && resultText.length > fullText.length) {\n const delta = resultText.slice(fullText.length)\n fullText = resultText\n if (delta) onDelta(delta, fullText)\n }\n }\n } catch {\n // Not JSON — could be raw text output, append it\n if (line.trim() && !line.startsWith(\"{\")) {\n fullText += line + \"\\n\"\n onDelta(line + \"\\n\", fullText)\n }\n }\n }\n })\n }\n\n const result = await proc\n\n // If we got no streaming content, fall back to stdout\n if (!fullText && result.stdout) {\n fullText = typeof result.stdout === \"string\" ? result.stdout : \"\"\n }\n\n if (result.exitCode !== 0 && !fullText) {\n const stderr = typeof result.stderr === \"string\" ? result.stderr : \"\"\n return {\n content: \"\",\n error: stderr || `Claude Code exited with code ${result.exitCode}`,\n duration: Date.now() - start,\n }\n }\n\n return {\n content: fullText,\n duration: Date.now() - start,\n }\n } catch (error: any) {\n return {\n content: fullText || \"\",\n error: error.message,\n duration: Date.now() - start,\n }\n }\n}\n\n/**\n * Execute a task using the Claude Agent SDK (tier: \"sdk\").\n */\nexport async function executeSdk(\n agent: AgentDef,\n task: AgentTask,\n apiKey: string,\n): Promise<AgentResponse> {\n const start = Date.now()\n\n try {\n // @ts-ignore — SDK may not be installed\n const sdk = await import(\"@anthropic-ai/claude-agent-sdk\")\n const { query } = sdk\n\n const prompt = agent.systemPrompt\n ? `${agent.systemPrompt}\\n\\n${task.message}`\n : task.message\n\n let content = \"\"\n\n const q = query({\n prompt,\n options: {\n model: agent.model,\n cwd: agent.workspace,\n permissionMode: \"bypassPermissions\" as any,\n },\n })\n\n for await (const message of q) {\n if (message.type === \"result\" && message.subtype === \"success\") {\n content = message.result || \"\"\n }\n }\n\n return {\n content,\n duration: Date.now() - start,\n }\n } catch (error: any) {\n return {\n content: \"\",\n error: `SDK error: ${error.message}`,\n duration: Date.now() - start,\n }\n }\n}\n\n/**\n * Execute a task using agentx's own orchestrator (tier: \"orchestrator\").\n */\nexport async function executeOrchestrator(\n agent: AgentDef,\n task: AgentTask,\n apiKey?: string,\n): Promise<AgentResponse> {\n const start = Date.now()\n\n try {\n const { generate } = await import(\"@/agent\")\n const providerName = agent.provider || \"claude-code\"\n\n const result = await generate({\n task: task.message,\n cwd: agent.workspace,\n provider: providerName as any,\n model: agent.model,\n apiKey,\n overwrite: true,\n interactive: false,\n context7: false,\n })\n\n return {\n content: result.content || \"Done.\",\n tokensUsed: result.tokensUsed,\n duration: Date.now() - start,\n }\n } catch (error: any) {\n return {\n content: \"\",\n error: `Orchestrator error: ${error.message}`,\n duration: Date.now() - start,\n }\n }\n}\n\n/**\n * Route a task to the correct execution tier.\n */\nexport async function executeTask(\n agent: AgentDef,\n task: AgentTask,\n providers: Record<string, { apiKey?: string }>,\n onDelta?: StreamCallback,\n historyContext?: string,\n resumeSessionId?: string,\n): Promise<AgentResponse> {\n switch (agent.tier) {\n case \"claude-code\":\n if (onDelta) {\n return executeClaudeCodeStreaming(agent, task, onDelta, historyContext, resumeSessionId)\n }\n return executeClaudeCode(agent, task, historyContext, resumeSessionId)\n\n case \"sdk\": {\n const providerName = agent.provider || \"claude\"\n const apiKey = providers[providerName]?.apiKey\n if (!apiKey) {\n return {\n content: \"\",\n error: `No API key for provider \"${providerName}\". Configure providers.${providerName}.apiKey`,\n }\n }\n return executeSdk(agent, task, apiKey)\n }\n\n case \"orchestrator\": {\n const providerName = agent.provider || \"claude-code\"\n const apiKey = providers[providerName]?.apiKey\n return executeOrchestrator(agent, task, apiKey)\n }\n\n default:\n return {\n content: \"\",\n error: `Unknown tier: ${agent.tier}`,\n }\n }\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"fs\"\nimport { resolve } from \"path\"\n\n// --- Conversation session store ---\n// One session per agent + channel + chatId + day.\n// For claude-code tier: stores the Claude session ID so we can --resume it.\n// For other tiers: stores message history as text, prepended to each prompt.\n\nexport interface SessionMessage {\n role: \"user\" | \"agent\"\n name?: string // sender name or agent name\n content: string\n timestamp: string\n}\n\nexport interface Session {\n id: string\n agentId: string\n channel: string\n chatId: string\n day: string // YYYY-MM-DD\n claudeSessionId?: string // Claude Code native session ID (for --resume)\n messages: SessionMessage[]\n createdAt: string\n updatedAt: string\n}\n\nconst MAX_HISTORY_CHARS = 12000 // Keep last ~12k chars of history to fit in context\nconst MAX_MESSAGES = 30 // Keep last 30 messages max\n\nexport class SessionStore {\n private sessionsDir: string\n private cache: Map<string, Session> = new Map()\n\n constructor(baseDir: string = process.cwd()) {\n this.sessionsDir = resolve(baseDir, \".agentx/sessions\")\n if (!existsSync(this.sessionsDir)) {\n mkdirSync(this.sessionsDir, { recursive: true })\n }\n }\n\n /**\n * Build a deterministic session key.\n */\n private sessionKey(agentId: string, channel: string, chatId: string): string {\n const day = new Date().toISOString().slice(0, 10) // YYYY-MM-DD\n return `${agentId}:${channel}:${chatId}:${day}`\n }\n\n private sessionFile(key: string): string {\n // Sanitize key for filesystem\n const safe = key.replace(/[^a-zA-Z0-9_:-]/g, \"_\")\n return resolve(this.sessionsDir, `${safe}.json`)\n }\n\n /**\n * Get or create a session for this agent+channel+chat+day.\n */\n getSession(agentId: string, channel: string, chatId: string): Session {\n const key = this.sessionKey(agentId, channel, chatId)\n\n // Check cache\n if (this.cache.has(key)) {\n return this.cache.get(key)!\n }\n\n // Try loading from disk\n const file = this.sessionFile(key)\n if (existsSync(file)) {\n try {\n const data = JSON.parse(readFileSync(file, \"utf-8\")) as Session\n this.cache.set(key, data)\n return data\n } catch {\n // Corrupted file — start fresh\n }\n }\n\n // Create new session\n const day = new Date().toISOString().slice(0, 10)\n const session: Session = {\n id: key,\n agentId,\n channel,\n chatId,\n day,\n messages: [],\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n\n this.cache.set(key, session)\n this.save(session)\n return session\n }\n\n /**\n * Add a user message to the session.\n */\n addUserMessage(agentId: string, channel: string, chatId: string, senderName: string, content: string): void {\n const session = this.getSession(agentId, channel, chatId)\n session.messages.push({\n role: \"user\",\n name: senderName,\n content,\n timestamp: new Date().toISOString(),\n })\n this.trim(session)\n session.updatedAt = new Date().toISOString()\n this.save(session)\n }\n\n /**\n * Add an agent response to the session.\n */\n addAgentMessage(agentId: string, channel: string, chatId: string, content: string): void {\n const session = this.getSession(agentId, channel, chatId)\n session.messages.push({\n role: \"agent\",\n name: agentId,\n content,\n timestamp: new Date().toISOString(),\n })\n this.trim(session)\n session.updatedAt = new Date().toISOString()\n this.save(session)\n }\n\n /**\n * Get the Claude Code session ID for this conversation (for --resume).\n * Returns undefined if no session yet (first message of the day).\n */\n getClaudeSessionId(agentId: string, channel: string, chatId: string): string | undefined {\n const session = this.getSession(agentId, channel, chatId)\n return session.claudeSessionId\n }\n\n /**\n * Store the Claude Code session ID after first invocation.\n */\n setClaudeSessionId(agentId: string, channel: string, chatId: string, claudeSessionId: string): void {\n const session = this.getSession(agentId, channel, chatId)\n session.claudeSessionId = claudeSessionId\n session.updatedAt = new Date().toISOString()\n this.save(session)\n }\n\n /**\n * Build conversation history string to prepend to the prompt.\n * Returns empty string if no history.\n * Used for non-claude-code tiers that don't have native sessions.\n */\n buildHistoryContext(agentId: string, channel: string, chatId: string): string {\n const session = this.getSession(agentId, channel, chatId)\n if (session.messages.length === 0) return \"\"\n\n const lines: string[] = [\n `[Conversation history for today (${session.day})]`,\n ]\n\n for (const msg of session.messages) {\n const time = msg.timestamp.slice(11, 16) // HH:MM\n if (msg.role === \"user\") {\n lines.push(`[${time}] ${msg.name || \"User\"}: ${msg.content}`)\n } else {\n lines.push(`[${time}] ${msg.name || \"Agent\"}: ${msg.content}`)\n }\n }\n\n lines.push(\"[End of history — respond to the latest message above]\")\n lines.push(\"\")\n\n return lines.join(\"\\n\")\n }\n\n /**\n * Trim session to stay within limits.\n */\n private trim(session: Session): void {\n // Trim by message count\n if (session.messages.length > MAX_MESSAGES) {\n session.messages = session.messages.slice(-MAX_MESSAGES)\n }\n\n // Trim by total character count\n let totalChars = session.messages.reduce((sum, m) => sum + m.content.length, 0)\n while (totalChars > MAX_HISTORY_CHARS && session.messages.length > 2) {\n const removed = session.messages.shift()!\n totalChars -= removed.content.length\n }\n }\n\n private save(session: Session): void {\n try {\n const file = this.sessionFile(session.id)\n writeFileSync(file, JSON.stringify(session, null, 2))\n } catch {\n // Best-effort persistence\n }\n }\n}\n","import type { DaemonConfig, AgentDef } from \"@/daemon/config\"\nimport { executeTask, type AgentTask, type AgentResponse, type StreamCallback, type AgentPeer } from \"./runtime\"\nimport { SessionStore } from \"./sessions\"\n\n// --- Agent Registry: lifecycle management + concurrency control ---\n\ninterface AgentState {\n id: string\n def: AgentDef\n activeTasks: number\n totalTasks: number\n lastActive?: Date\n errors: number\n}\n\nexport class AgentRegistry {\n private agents: Map<string, AgentState> = new Map()\n private config: DaemonConfig\n private providers: Record<string, { apiKey?: string }> = {}\n private sessions: SessionStore\n private log: (...args: unknown[]) => void\n\n constructor(\n config: DaemonConfig,\n log: (...args: unknown[]) => void = console.error.bind(console, \"[agents]\"),\n ) {\n this.log = log\n this.config = config\n this.providers = config.providers\n this.sessions = new SessionStore()\n\n for (const [id, def] of Object.entries(config.agents)) {\n this.agents.set(id, {\n id,\n def,\n activeTasks: 0,\n totalTasks: 0,\n errors: 0,\n })\n }\n }\n\n /**\n * Get agent definition by ID.\n */\n getAgent(id: string): AgentDef | undefined {\n return this.agents.get(id)?.def\n }\n\n /**\n * Find agent by mention pattern (e.g., \"@nadia\" -> \"marketing-agent\").\n * Returns the agent with the longest (most specific) mention match.\n */\n findByMention(text: string): string | undefined {\n const lower = text.toLowerCase()\n let bestId: string | undefined\n let bestLen = 0\n\n for (const [id, state] of this.agents) {\n for (const mention of state.def.mentions) {\n const mentionLower = mention.toLowerCase()\n if (lower.includes(mentionLower) && mentionLower.length > bestLen) {\n bestId = id\n bestLen = mentionLower.length\n }\n }\n }\n\n return bestId\n }\n\n /**\n * Find ALL agents mentioned in text (for bot-to-bot detection).\n */\n findAllMentioned(text: string): string[] {\n const lower = text.toLowerCase()\n const found: string[] = []\n\n for (const [id, state] of this.agents) {\n for (const mention of state.def.mentions) {\n if (lower.includes(mention.toLowerCase())) {\n found.push(id)\n break\n }\n }\n }\n\n return found\n }\n\n /**\n * Get the primary channel handle for an agent (e.g. \"@noqta_devops_bot\" on telegram).\n */\n private getChannelHandle(agentId: string, channel?: string): string | undefined {\n const agent = this.agents.get(agentId)?.def\n if (!agent) return undefined\n\n // For telegram, find the mention that starts with @ (bot username)\n if (channel === \"telegram\") {\n return agent.mentions.find((m) => m.startsWith(\"@\"))\n }\n\n // Fallback: first mention\n return agent.mentions[0]\n }\n\n /**\n * Enrich the task context with peer roster and channel handles.\n */\n private enrichTaskContext(task: AgentTask): AgentTask {\n const channel = task.context?.channel\n\n // Build peer list (all agents except self)\n const peers: AgentPeer[] = []\n for (const [id, state] of this.agents) {\n if (id === task.agentId) continue\n peers.push({\n id,\n name: state.def.name,\n handle: this.getChannelHandle(id, channel),\n role: state.def.systemPrompt?.split(\"\\n\")[0]?.slice(0, 100),\n })\n }\n\n // Get own handle\n const myHandle = this.getChannelHandle(task.agentId, channel)\n\n return {\n ...task,\n context: {\n ...task.context,\n myHandle,\n peers,\n },\n }\n }\n\n /**\n * Execute a task on an agent. Respects maxConcurrent limit.\n */\n async execute(task: AgentTask, onDelta?: StreamCallback): Promise<AgentResponse> {\n const state = this.agents.get(task.agentId)\n if (!state) {\n return { content: \"\", error: `Unknown agent: ${task.agentId}` }\n }\n\n if (state.activeTasks >= state.def.maxConcurrent) {\n return {\n content: \"\",\n error: `Agent \"${task.agentId}\" is busy (${state.activeTasks}/${state.def.maxConcurrent} tasks)`,\n }\n }\n\n state.activeTasks++\n state.totalTasks++\n state.lastActive = new Date()\n\n this.log(`[${task.agentId}] executing task (${state.activeTasks}/${state.def.maxConcurrent})`)\n\n // Build conversation history for session continuity\n const channel = task.context?.channel || \"api\"\n const chatId = task.context?.group || task.context?.sender || \"default\"\n const senderName = task.context?.sender || \"User\"\n\n // Record user message in session\n this.sessions.addUserMessage(task.agentId, channel, chatId, senderName, task.message)\n\n // Enrich task context with peer info and channel handles\n task = this.enrichTaskContext(task)\n\n // For claude-code tier: use native --resume with Claude session ID\n // For other tiers: use manual history context\n const resumeSessionId = state.def.tier === \"claude-code\"\n ? this.sessions.getClaudeSessionId(task.agentId, channel, chatId)\n : undefined\n const historyContext = state.def.tier !== \"claude-code\"\n ? this.sessions.buildHistoryContext(task.agentId, channel, chatId)\n : undefined\n\n try {\n const response = await executeTask(state.def, task, this.providers, onDelta, historyContext, resumeSessionId)\n\n if (response.error) {\n state.errors++\n this.log(`[${task.agentId}] error: ${response.error}`)\n } else {\n // Record agent response in session\n this.sessions.addAgentMessage(task.agentId, channel, chatId, response.content)\n\n // Store Claude session ID for future --resume\n if (response.claudeSessionId) {\n this.sessions.setClaudeSessionId(task.agentId, channel, chatId, response.claudeSessionId)\n this.log(`[${task.agentId}] session: ${response.claudeSessionId}`)\n }\n\n this.log(\n `[${task.agentId}] completed in ${response.duration}ms` +\n (response.tokensUsed ? ` (${response.tokensUsed} tokens)` : \"\"),\n )\n }\n\n return response\n } catch (error: any) {\n state.errors++\n this.log(`[${task.agentId}] unexpected error: ${error.message}`)\n return { content: \"\", error: error.message }\n } finally {\n state.activeTasks--\n }\n }\n\n /**\n * List all agents and their status.\n */\n list(): Array<{\n id: string\n name: string\n tier: string\n workspace: string\n active: number\n total: number\n errors: number\n lastActive?: Date\n }> {\n return Array.from(this.agents.values()).map((s) => ({\n id: s.id,\n name: s.def.name,\n tier: s.def.tier,\n workspace: s.def.workspace,\n active: s.activeTasks,\n total: s.totalTasks,\n errors: s.errors,\n lastActive: s.lastActive,\n }))\n }\n}\n","import type { DaemonConfig } from \"@/daemon/config\"\nimport type { AgentRegistry } from \"@/agents/registry\"\nimport type { ChannelAdapter, IncomingMessage } from \"./types\"\nimport type { TelegramAdapter } from \"./telegram\"\nimport type { HookRegistry } from \"@/hooks\"\n\n// --- Message Router ---\n// Routes channel messages to agents. Supports:\n// - Typing indicator while processing\n// - Streaming response edits\n// - Seen reaction (👀) on mention\n// - Bot-to-bot: if response mentions another agent, route it\n// - Correct bot account sends the reply (not always the first one)\n\nconst STREAM_EDIT_INTERVAL_MS = 1500\nconst TYPING_INTERVAL_MS = 4000\n\nexport class MessageRouter {\n private registry: AgentRegistry\n private config: DaemonConfig\n private channels: Map<string, ChannelAdapter> = new Map()\n private hooks?: HookRegistry\n private log: (...args: unknown[]) => void\n\n constructor(\n registry: AgentRegistry,\n config: DaemonConfig,\n hooks?: HookRegistry,\n log: (...args: unknown[]) => void = console.error.bind(console, \"[router]\"),\n ) {\n this.registry = registry\n this.config = config\n this.hooks = hooks\n this.log = log\n }\n\n addChannel(adapter: ChannelAdapter): void {\n this.channels.set(adapter.name, adapter)\n adapter.onMessage((msg) => this.handleMessage(adapter, msg))\n }\n\n async startAll(): Promise<void> {\n for (const [name, adapter] of this.channels) {\n this.log(`Starting channel: ${name}`)\n await adapter.start()\n }\n }\n\n async stopAll(): Promise<void> {\n for (const [name, adapter] of this.channels) {\n this.log(`Stopping channel: ${name}`)\n await adapter.stop()\n }\n }\n\n private async handleMessage(\n adapter: ChannelAdapter,\n msg: IncomingMessage,\n ): Promise<void> {\n // Pre-hook\n if (this.hooks?.has(\"pre:channel-message\" as any)) {\n const hookResult = await this.hooks.execute(\"pre:channel-message\" as any, {\n event: \"pre:channel-message\" as any,\n channel: msg.channel,\n sender: msg.sender.name,\n text: msg.text,\n group: msg.group?.name,\n })\n\n if (hookResult.blocked) {\n this.log(`Message blocked by hook: ${hookResult.message}`)\n return\n }\n\n if (hookResult.modified?.text) {\n msg = { ...msg, text: hookResult.modified.text as string }\n }\n }\n\n // Resolve agent\n const agentId = this.resolveAgent(msg)\n if (!agentId) {\n return\n }\n\n // Dedup: in groups, multiple bot accounts receive the same message.\n // Only the account BOUND to this agent should handle it.\n if (msg.group && msg.channel === \"telegram\") {\n const boundAccount = this.getAccountForAgent(agentId)\n if (boundAccount && boundAccount !== msg.accountId) {\n return\n }\n }\n\n const chatId = msg.group?.id || msg.sender.id\n const agentDef = this.registry.getAgent(agentId)\n const agentName = agentDef?.name || agentId\n\n // Determine which bot account should send the response\n const replyAccountId = this.getAccountForAgent(agentId) || msg.accountId\n\n this.log(\n `Routing [${msg.channel}/${msg.sender.name}] -> \"${agentName}\": ${msg.text.slice(0, 80)}`,\n )\n\n // React with 👀 to acknowledge\n this.adapterReact(adapter, chatId, msg.id, \"👀\", replyAccountId)\n\n // Start typing indicator loop (from the correct bot)\n const typingTimer = this.startTypingLoop(adapter, chatId, replyAccountId)\n\n // Streaming setup\n const canStream = typeof adapter.editMessage === \"function\"\n let sentMessageId: string | undefined\n let lastEditTime = 0\n\n const onDelta = canStream\n ? async (_delta: string, fullText: string) => {\n const now = Date.now()\n if (now - lastEditTime < STREAM_EDIT_INTERVAL_MS) return\n\n if (!sentMessageId) {\n const preview = fullText.length > 20\n ? fullText\n : `_${agentName} is writing..._\\n\\n${fullText}`\n try {\n sentMessageId = await this.adapterSend(adapter, {\n channel: msg.channel,\n chatId,\n text: preview,\n replyTo: msg.id,\n accountId: replyAccountId,\n })\n lastEditTime = now\n } catch { /* retry next delta */ }\n } else {\n try {\n await this.adapterEdit(adapter, chatId, sentMessageId, fullText, undefined, replyAccountId)\n lastEditTime = now\n } catch { /* retry next delta */ }\n }\n }\n : undefined\n\n // Execute agent task\n const response = await this.registry.execute(\n {\n message: msg.text,\n agentId,\n context: {\n channel: msg.channel,\n sender: msg.sender.name,\n group: msg.group?.name,\n },\n },\n onDelta,\n )\n\n clearInterval(typingTimer)\n\n if (response.error) {\n this.log(`Agent error: ${response.error}`)\n const errorText = `Error: ${response.error}`\n if (sentMessageId) {\n await this.adapterEdit(adapter, chatId, sentMessageId, errorText, \"plain\", replyAccountId)\n } else {\n await this.adapterSend(adapter, {\n channel: msg.channel,\n chatId,\n text: errorText,\n replyTo: msg.id,\n parseMode: \"plain\",\n accountId: replyAccountId,\n })\n }\n return\n }\n\n // Post-hook\n let responseText = response.content\n if (this.hooks?.has(\"post:channel-message\" as any)) {\n const hookResult = await this.hooks.execute(\"post:channel-message\" as any, {\n event: \"post:channel-message\" as any,\n channel: msg.channel,\n sender: msg.sender.name,\n response: responseText,\n agentId,\n })\n\n if (hookResult.blocked) {\n this.log(`Response blocked by hook: ${hookResult.message}`)\n return\n }\n\n if (hookResult.modified?.response) {\n responseText = hookResult.modified.response as string\n }\n }\n\n // Final message\n let sentResponseId: string | undefined\n if (responseText) {\n if (sentMessageId) {\n await this.adapterEdit(adapter, chatId, sentMessageId, responseText, undefined, replyAccountId)\n sentResponseId = sentMessageId\n } else {\n sentResponseId = await this.adapterSend(adapter, {\n channel: msg.channel,\n chatId,\n text: responseText,\n replyTo: msg.id,\n accountId: replyAccountId,\n })\n }\n }\n\n // Bot-to-bot: if response mentions another agent, route it (fire-and-forget with error handling)\n if (responseText && sentResponseId) {\n this.handleBotToBotMentions(adapter, msg, agentId, responseText, sentResponseId).catch((e) => {\n this.log(`Bot-to-bot error: ${e.message}`)\n })\n }\n }\n\n /**\n * Check if an agent's response mentions another agent.\n * If so, route the response as a new task to that agent.\n */\n private async handleBotToBotMentions(\n adapter: ChannelAdapter,\n originalMsg: IncomingMessage,\n sourceAgentId: string,\n responseText: string,\n responseMessageId: string,\n ): Promise<void> {\n for (const [id, def] of Object.entries(this.config.agents)) {\n if (id === sourceAgentId) continue\n\n const mentioned = def.mentions.some((m: string) =>\n responseText.toLowerCase().includes(m.toLowerCase()),\n )\n if (!mentioned) continue\n\n this.log(`Bot-to-bot: \"${sourceAgentId}\" mentioned \"${id}\" — routing`)\n\n const chatId = originalMsg.group?.id || originalMsg.sender.id\n const targetAccountId = this.getAccountForAgent(id)\n\n try {\n // Seen reaction from the target bot on the source bot's message\n this.adapterReact(adapter, chatId, responseMessageId, \"👀\", targetAccountId)\n\n // Typing from the target bot\n const typingTimer = this.startTypingLoop(adapter, chatId, targetAccountId)\n\n const response = await this.registry.execute({\n message: responseText,\n agentId: id,\n context: {\n channel: originalMsg.channel,\n sender: `agent:${sourceAgentId}`,\n group: originalMsg.group?.name,\n },\n })\n\n clearInterval(typingTimer)\n\n if (response.content && !response.error) {\n // Send as a new message (not a reply) to avoid \"message to reply not found\" errors\n // when the target bot can't resolve the source bot's message ID\n await this.adapterSend(adapter, {\n channel: originalMsg.channel,\n chatId,\n text: response.content,\n accountId: targetAccountId,\n })\n } else if (response.error) {\n this.log(`Bot-to-bot \"${id}\" error: ${response.error}`)\n }\n } catch (e: any) {\n this.log(`Bot-to-bot \"${id}\" failed: ${e.message}`)\n }\n\n break // Only route to first mentioned agent\n }\n }\n\n // --- Adapter helpers that pass accountId for Telegram ---\n\n private async adapterSend(\n adapter: ChannelAdapter,\n msg: { channel: string; chatId: string; text: string; replyTo?: string; parseMode?: string; accountId?: string },\n ): Promise<string> {\n // For Telegram, pass accountId so the correct bot sends the message\n if (adapter.name === \"telegram\" && msg.accountId) {\n return (adapter as TelegramAdapter).send({\n ...msg,\n parseMode: msg.parseMode as any,\n accountId: msg.accountId,\n }) as Promise<string>\n }\n return (adapter.send(msg as any) || \"\") as Promise<string>\n }\n\n private async adapterEdit(\n adapter: ChannelAdapter,\n chatId: string,\n messageId: string,\n text: string,\n parseMode?: string,\n accountId?: string,\n ): Promise<boolean> {\n if (adapter.name === \"telegram\" && accountId) {\n return (adapter as TelegramAdapter).editMessage(chatId, messageId, text, parseMode, accountId)\n }\n return adapter.editMessage?.(chatId, messageId, text, parseMode) ?? false\n }\n\n private adapterReact(\n adapter: ChannelAdapter,\n chatId: string,\n messageId: string,\n emoji: string,\n accountId?: string,\n ): void {\n if (adapter.name === \"telegram\" && accountId) {\n (adapter as TelegramAdapter).react(chatId, messageId, emoji, accountId)\n } else {\n adapter.react?.(chatId, messageId, emoji)\n }\n }\n\n private startTypingLoop(\n adapter: ChannelAdapter,\n chatId: string,\n accountId?: string,\n ): ReturnType<typeof setInterval> {\n const sendTyping = () => {\n if (adapter.name === \"telegram\" && accountId) {\n (adapter as TelegramAdapter).sendTyping(chatId, accountId)\n } else {\n adapter.sendTyping?.(chatId)\n }\n }\n\n sendTyping()\n return setInterval(sendTyping, TYPING_INTERVAL_MS)\n }\n\n // --- Agent resolution ---\n\n private getAccountForAgent(agentId: string): string | undefined {\n for (const [accountId, account] of Object.entries(this.config.channels.telegram.accounts)) {\n if (account.agentBinding === agentId) {\n return accountId\n }\n }\n return undefined\n }\n\n private resolveAgent(msg: IncomingMessage): string | undefined {\n // DM: route to the account's bound agent\n if (!msg.group) {\n if (msg.channel === \"telegram\") {\n const account = this.config.channels.telegram.accounts[msg.accountId]\n return account?.agentBinding\n }\n if (msg.channel === \"whatsapp\") {\n return this.config.channels.whatsapp.agentBinding\n }\n return undefined\n }\n\n // Group: check policy\n if (msg.channel === \"telegram\") {\n const policy = this.config.channels.telegram.policy\n if (policy.group === \"mention-required\") {\n const agentId = this.registry.findByMention(msg.text)\n if (!agentId) return undefined\n return agentId\n }\n }\n\n // Default: mention matching, then account binding\n const mentionAgent = this.registry.findByMention(msg.text)\n if (mentionAgent) return mentionAgent\n\n if (msg.channel === \"telegram\") {\n const account = this.config.channels.telegram.accounts[msg.accountId]\n return account?.agentBinding\n }\n\n return this.config.channels.whatsapp.agentBinding\n }\n}\n","// --- Convert standard Markdown (Claude output) to Telegram MarkdownV2 ---\n//\n// Telegram MarkdownV2 requires escaping 18 special chars outside entities:\n// _ * [ ] ( ) ~ ` > # + - = | { } . !\n//\n// Supported entities: *bold*, _italic_, __underline__, ~strikethrough~,\n// ||spoiler||, `code`, ```pre```, [link](url)\n\n// Characters that must be escaped in normal text\nconst SPECIAL = /([_*\\[\\]()~`>#+=|{}.!\\-\\\\])/g\n\n/**\n * Escape special characters for MarkdownV2 plain text.\n */\nfunction esc(text: string): string {\n return text.replace(SPECIAL, \"\\\\$1\")\n}\n\n/**\n * Escape only backtick and backslash inside code/pre blocks.\n */\nfunction escCode(text: string): string {\n return text.replace(/([`\\\\])/g, \"\\\\$1\")\n}\n\n/**\n * Convert standard Markdown to Telegram MarkdownV2.\n *\n * Handles: headers, bold, italic, inline code, code blocks, links, lists, blockquotes.\n * Designed for Claude's output style.\n */\nexport function markdownToTelegramV2(md: string): string {\n const lines = md.split(\"\\n\")\n const result: string[] = []\n let inCodeBlock = false\n let codeBlockLang = \"\"\n let codeBlockLines: string[] = []\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n\n // Code block toggle\n if (line.trimStart().startsWith(\"```\")) {\n if (!inCodeBlock) {\n inCodeBlock = true\n codeBlockLang = line.trimStart().slice(3).trim()\n codeBlockLines = []\n continue\n } else {\n // Close code block\n inCodeBlock = false\n const code = codeBlockLines.join(\"\\n\")\n if (codeBlockLang) {\n result.push(\"```\" + escCode(codeBlockLang))\n } else {\n result.push(\"```\")\n }\n result.push(escCode(code))\n result.push(\"```\")\n continue\n }\n }\n\n if (inCodeBlock) {\n codeBlockLines.push(line)\n continue\n }\n\n // Headers → bold text\n const headerMatch = line.match(/^(#{1,6})\\s+(.+)$/)\n if (headerMatch) {\n result.push(\"\")\n result.push(\"*\" + escInline(headerMatch[2]) + \"*\")\n continue\n }\n\n // Horizontal rule\n if (/^[-*_]{3,}\\s*$/.test(line.trim())) {\n result.push(\"———\")\n continue\n }\n\n // Blockquote\n if (line.trimStart().startsWith(\"> \")) {\n const content = line.replace(/^>\\s*/, \"\")\n result.push(\">\" + convertInline(content))\n continue\n }\n\n // Unordered list\n const ulMatch = line.match(/^(\\s*)[-*+]\\s+(.+)$/)\n if (ulMatch) {\n const indent = ulMatch[1].length > 0 ? \" \" : \"\"\n result.push(indent + \"• \" + convertInline(ulMatch[2]))\n continue\n }\n\n // Ordered list\n const olMatch = line.match(/^(\\s*)\\d+[.)]\\s+(.+)$/)\n if (olMatch) {\n const indent = olMatch[1].length > 0 ? \" \" : \"\"\n const num = line.match(/^(\\s*)(\\d+)/)?.[2] || \"1\"\n result.push(indent + esc(num) + \"\\\\. \" + convertInline(olMatch[2]))\n continue\n }\n\n // Empty line\n if (!line.trim()) {\n result.push(\"\")\n continue\n }\n\n // Normal text\n result.push(convertInline(line))\n }\n\n // Handle unclosed code block\n if (inCodeBlock) {\n result.push(\"```\")\n result.push(escCode(codeBlockLines.join(\"\\n\")))\n result.push(\"```\")\n }\n\n return result.join(\"\\n\").trim()\n}\n\n/**\n * Convert inline markdown elements: bold, italic, code, links.\n */\nfunction convertInline(text: string): string {\n // First, extract and protect inline code spans\n const codeSpans: string[] = []\n let processed = text.replace(/`([^`]+)`/g, (_match, code) => {\n const idx = codeSpans.length\n codeSpans.push(\"`\" + escCode(code) + \"`\")\n return `\\x00CODE${idx}\\x00`\n })\n\n // Extract and protect @mentions (Telegram usernames contain letters, digits, underscores)\n const mentions: string[] = []\n processed = processed.replace(/@(\\w{5,})/g, (_match, username) => {\n const idx = mentions.length\n mentions.push(\"@\" + esc(username))\n return `\\x00MENTION${idx}\\x00`\n })\n\n // Extract and protect links\n const links: string[] = []\n processed = processed.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_match, label, url) => {\n const idx = links.length\n links.push(\"[\" + escInline(label) + \"](\" + url.replace(/([)\\\\])/g, \"\\\\$1\") + \")\")\n return `\\x00LINK${idx}\\x00`\n })\n\n // Bold+italic: ***text*** or ___text___\n processed = processed.replace(/\\*\\*\\*(.+?)\\*\\*\\*/g, (_m, t) => \"*_\" + esc(t) + \"_*\")\n\n // Bold: **text** → *text*\n processed = processed.replace(/\\*\\*(.+?)\\*\\*/g, (_m, t) => \"*\" + esc(t) + \"*\")\n\n // Italic: *text* or _text_ → _text_\n // Be careful not to match already-converted bold markers\n processed = processed.replace(/(?<!\\*)\\*([^*]+?)\\*(?!\\*)/g, (_m, t) => \"_\" + esc(t) + \"_\")\n processed = processed.replace(/(?<!_)_([^_]+?)_(?!_)/g, (_m, t) => \"_\" + esc(t) + \"_\")\n\n // Strikethrough: ~~text~~ → ~text~\n processed = processed.replace(/~~(.+?)~~/g, (_m, t) => \"~\" + esc(t) + \"~\")\n\n // Escape remaining plain text (but preserve our placeholders and already-formatted entities)\n processed = escPlainSegments(processed)\n\n // Restore protected tokens\n processed = processed.replace(/\\x00CODE(\\d+)\\x00/g, (_m, idx) => codeSpans[parseInt(idx)])\n processed = processed.replace(/\\x00MENTION(\\d+)\\x00/g, (_m, idx) => mentions[parseInt(idx)])\n processed = processed.replace(/\\x00LINK(\\d+)\\x00/g, (_m, idx) => links[parseInt(idx)])\n\n return processed\n}\n\n/**\n * Escape text that appears inside a formatting entity (already wrapped in * or _).\n */\nfunction escInline(text: string): string {\n return esc(text)\n}\n\n/**\n * Escape special chars in plain text segments only (not inside formatting markers).\n * This is a simplified approach: escape any special char that isn't part of a\n * formatting entity we already placed.\n */\nfunction escPlainSegments(text: string): string {\n // Split on our formatting markers and placeholders (including MENTION)\n const parts = text.split(/(\\*[^*]+\\*|_[^_]+_|~[^~]+~|\\x00\\w+\\d+\\x00)/g)\n\n return parts\n .map((part) => {\n // Keep formatted entities and placeholders as-is\n if (\n /^\\*[^*]+\\*$/.test(part) ||\n /^_[^_]+_$/.test(part) ||\n /^~[^~]+~$/.test(part) ||\n /^\\x00/.test(part)\n ) {\n return part\n }\n // Escape plain text\n return esc(part)\n })\n .join(\"\")\n}\n","import type { ChannelAdapter, IncomingMessage, OutgoingMessage } from \"./types\"\nimport { markdownToTelegramV2 } from \"./telegram-format\"\n\n// --- Telegram Bot API adapter (long-polling, no dependencies) ---\n\ninterface TelegramUpdate {\n update_id: number\n message?: {\n message_id: number\n from: { id: number; first_name: string; last_name?: string; username?: string }\n chat: { id: number; type: string; title?: string }\n text?: string\n date: number\n reply_to_message?: { message_id: number }\n }\n}\n\ninterface TelegramAccountConfig {\n token: string\n agentBinding: string\n}\n\nexport class TelegramAdapter implements ChannelAdapter {\n readonly name = \"telegram\"\n private accounts: Map<string, TelegramAccountConfig>\n private offsets: Map<string, number> = new Map()\n private handler?: (msg: IncomingMessage) => Promise<void>\n private polling = false\n private log: (...args: unknown[]) => void\n\n constructor(\n accounts: Record<string, TelegramAccountConfig>,\n log: (...args: unknown[]) => void = console.error.bind(console, \"[telegram]\"),\n ) {\n this.accounts = new Map(Object.entries(accounts))\n this.log = log\n }\n\n onMessage(handler: (msg: IncomingMessage) => Promise<void>): void {\n this.handler = handler\n }\n\n async start(): Promise<void> {\n this.polling = true\n\n for (const [accountId, config] of this.accounts) {\n this.log(`Starting polling for account \"${accountId}\"`)\n try {\n const me = await this.apiCall(config.token, \"getMe\")\n this.log(`Bot @${me.result?.username} ready (account: ${accountId})`)\n } catch (e: any) {\n this.log(`Failed to verify bot for account \"${accountId}\": ${e.message}`)\n continue\n }\n\n this.pollLoop(accountId, config)\n }\n }\n\n async stop(): Promise<void> {\n this.polling = false\n }\n\n /**\n * Get token for a specific account ID. Used by router to send from correct bot.\n */\n getTokenForAccount(accountId: string): string | undefined {\n return this.accounts.get(accountId)?.token\n }\n\n /**\n * Get the default (first) account token as fallback.\n */\n private getDefaultToken(): string | undefined {\n const [, config] = Array.from(this.accounts.entries())[0]\n return config?.token\n }\n\n /**\n * Resolve which token to use: prefer accountId, fall back to chatAccountMap, then default.\n */\n private resolveToken(chatId: string, accountId?: string): string | undefined {\n if (accountId) {\n const token = this.getTokenForAccount(accountId)\n if (token) return token\n }\n return this.chatAccountMap.get(chatId)\n ? this.getTokenForAccount(this.chatAccountMap.get(chatId)!)\n : this.getDefaultToken()\n }\n\n /** Track which account a chat was last seen on (for DMs) */\n private chatAccountMap: Map<string, string> = new Map()\n\n /**\n * Send a message. Returns the sent message ID.\n * Pass accountId to send from a specific bot account.\n */\n async send(msg: OutgoingMessage & { accountId?: string }): Promise<string> {\n const token = this.resolveToken(msg.chatId, msg.accountId)\n if (!token) {\n this.log(\"No telegram token found for sending\")\n return \"\"\n }\n\n const maxLen = 4096\n const text = msg.text.length > maxLen ? msg.text.slice(0, maxLen - 3) + \"...\" : msg.text\n\n // Convert markdown to Telegram MarkdownV2\n const formatted = msg.parseMode === \"markdown\" || msg.parseMode === undefined\n ? markdownToTelegramV2(text)\n : text\n\n const params: Record<string, unknown> = {\n chat_id: msg.chatId,\n text: formatted,\n parse_mode: \"MarkdownV2\",\n }\n\n if (msg.replyTo) {\n params.reply_to_message_id = parseInt(msg.replyTo, 10)\n }\n\n if (msg.parseMode === \"html\") {\n params.parse_mode = \"HTML\"\n params.text = text\n } else if (msg.parseMode === \"plain\") {\n delete params.parse_mode\n params.text = text\n }\n\n try {\n const result = await this.apiCall(token, \"sendMessage\", params)\n return String(result.result?.message_id || \"\")\n } catch (e: any) {\n // Retry without formatting if MarkdownV2 fails\n if (params.parse_mode) {\n delete params.parse_mode\n params.text = text\n const result = await this.apiCall(token, \"sendMessage\", params)\n return String(result.result?.message_id || \"\")\n }\n throw e\n }\n }\n\n /**\n * Edit an existing message (for streaming updates).\n */\n async editMessage(chatId: string, messageId: string, text: string, parseMode?: string, accountId?: string): Promise<boolean> {\n const token = this.resolveToken(chatId, accountId)\n if (!token) return false\n\n const maxLen = 4096\n const trimmed = text.length > maxLen ? text.slice(0, maxLen - 3) + \"...\" : text\n\n const formatted = parseMode !== \"html\" && parseMode !== \"plain\"\n ? markdownToTelegramV2(trimmed)\n : trimmed\n\n const params: Record<string, unknown> = {\n chat_id: chatId,\n message_id: parseInt(messageId, 10),\n text: formatted,\n parse_mode: \"MarkdownV2\",\n }\n\n if (parseMode === \"html\") {\n params.parse_mode = \"HTML\"\n params.text = trimmed\n } else if (parseMode === \"plain\") {\n delete params.parse_mode\n params.text = trimmed\n }\n\n try {\n await this.apiCall(token, \"editMessageText\", params)\n return true\n } catch (e: any) {\n if (e.message?.includes(\"message is not modified\")) return true\n if (params.parse_mode) {\n delete params.parse_mode\n params.text = trimmed\n try {\n await this.apiCall(token, \"editMessageText\", params)\n return true\n } catch { return false }\n }\n return false\n }\n }\n\n /**\n * React to a message with an emoji.\n */\n async react(chatId: string, messageId: string, emoji: string = \"👀\", accountId?: string): Promise<void> {\n const token = this.resolveToken(chatId, accountId)\n if (!token) return\n\n try {\n await this.apiCall(token, \"setMessageReaction\", {\n chat_id: chatId,\n message_id: parseInt(messageId, 10),\n reaction: [{ type: \"emoji\", emoji }],\n })\n } catch {\n // Best-effort\n }\n }\n\n /**\n * Send typing indicator.\n */\n async sendTyping(chatId: string, accountId?: string): Promise<void> {\n const token = this.resolveToken(chatId, accountId)\n if (!token) return\n\n try {\n await this.apiCall(token, \"sendChatAction\", {\n chat_id: chatId,\n action: \"typing\",\n })\n } catch {\n // Best-effort\n }\n }\n\n // --- Internal ---\n\n private async pollLoop(accountId: string, config: TelegramAccountConfig): Promise<void> {\n while (this.polling) {\n try {\n const offset = this.offsets.get(accountId) || 0\n const data = await this.apiCall(config.token, \"getUpdates\", {\n offset: offset || undefined,\n timeout: 30,\n allowed_updates: [\"message\"],\n })\n\n const updates: TelegramUpdate[] = data.result || []\n\n for (const update of updates) {\n this.offsets.set(accountId, update.update_id + 1)\n\n if (update.message?.text && this.handler) {\n const msg = update.message\n const incoming: IncomingMessage = {\n id: String(msg.message_id),\n channel: \"telegram\",\n accountId,\n sender: {\n id: String(msg.from.id),\n name: [msg.from.first_name, msg.from.last_name].filter(Boolean).join(\" \"),\n username: msg.from.username,\n },\n group: msg.chat.type !== \"private\"\n ? { id: String(msg.chat.id), name: msg.chat.title || \"\" }\n : undefined,\n text: msg.text!,\n replyTo: msg.reply_to_message\n ? String(msg.reply_to_message.message_id)\n : undefined,\n timestamp: new Date(msg.date * 1000),\n raw: update,\n }\n\n // Track chat→account mapping for DM replies\n this.chatAccountMap.set(String(msg.chat.id), accountId)\n\n this.handler(incoming).catch((e) => {\n this.log(`Error handling message: ${e.message}`)\n })\n }\n }\n } catch (e: any) {\n this.log(`Poll error (${accountId}): ${e.message}`)\n await new Promise((r) => setTimeout(r, 5000))\n }\n }\n }\n\n private async apiCall(\n token: string,\n method: string,\n params?: Record<string, unknown>,\n ): Promise<any> {\n const url = `https://api.telegram.org/bot${token}/${method}`\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: params ? JSON.stringify(params) : undefined,\n })\n\n if (!res.ok) {\n const text = await res.text()\n throw new Error(`Telegram API error: ${res.status} ${text}`)\n }\n\n return res.json()\n }\n}\n","import type { ChannelAdapter, IncomingMessage, OutgoingMessage } from \"./types\"\n\n// --- WhatsApp adapter (placeholder — requires baileys or WA Business API) ---\n// This is a scaffold. Real implementation depends on chosen WhatsApp library.\n\nexport class WhatsAppAdapter implements ChannelAdapter {\n readonly name = \"whatsapp\"\n private sessionDir: string\n private agentBinding?: string\n private handler?: (msg: IncomingMessage) => Promise<void>\n private log: (...args: unknown[]) => void\n\n constructor(\n config: { sessionDir: string; agentBinding?: string },\n log: (...args: unknown[]) => void = console.error.bind(console, \"[whatsapp]\"),\n ) {\n this.sessionDir = config.sessionDir\n this.agentBinding = config.agentBinding\n this.log = log\n }\n\n onMessage(handler: (msg: IncomingMessage) => Promise<void>): void {\n this.handler = handler\n }\n\n async start(): Promise<void> {\n this.log(\"WhatsApp adapter is a placeholder.\")\n this.log(\"To enable, install @whiskeysockets/baileys and implement the connection logic.\")\n this.log(`Session dir: ${this.sessionDir}`)\n this.log(`Agent binding: ${this.agentBinding || \"(none)\"}`)\n\n // TODO: Implement with Baileys:\n // 1. const { default: makeWASocket, useMultiFileAuthState } = await import(\"@whiskeysockets/baileys\")\n // 2. const { state, saveCreds } = await useMultiFileAuthState(this.sessionDir)\n // 3. const sock = makeWASocket({ auth: state })\n // 4. sock.ev.on(\"messages.upsert\", ...) -> convert to IncomingMessage -> this.handler(msg)\n // 5. On first run, print QR code for pairing\n }\n\n async stop(): Promise<void> {\n // Close WhatsApp socket\n }\n\n async send(msg: OutgoingMessage): Promise<void> {\n this.log(`[send] Would send to ${msg.chatId}: ${msg.text.slice(0, 100)}...`)\n // TODO: sock.sendMessage(msg.chatId, { text: msg.text })\n }\n}\n","import type { DaemonConfig, CronJobDef } from \"@/daemon/config\"\nimport type { AgentRegistry } from \"@/agents/registry\"\nimport type { HookRegistry } from \"@/hooks\"\nimport type { CronJobState, CronRunResult } from \"./types\"\nimport { writeFileSync, mkdirSync, existsSync } from \"fs\"\nimport { resolve } from \"path\"\n\n// --- Cron Scheduler: lightweight cron engine with timezone support ---\n// No external dependencies — uses setTimeout-based scheduling.\n\n/**\n * Parse a cron expression into next-fire timestamp.\n * Supports standard 5-field format: minute hour day-of-month month day-of-week\n */\nfunction parseCronField(field: string, min: number, max: number): number[] {\n const values: number[] = []\n\n for (const part of field.split(\",\")) {\n if (part === \"*\") {\n for (let i = min; i <= max; i++) values.push(i)\n } else if (part.includes(\"/\")) {\n const [range, stepStr] = part.split(\"/\")\n const step = parseInt(stepStr, 10)\n const start = range === \"*\" ? min : parseInt(range, 10)\n for (let i = start; i <= max; i += step) values.push(i)\n } else if (part.includes(\"-\")) {\n const [a, b] = part.split(\"-\").map(Number)\n for (let i = a; i <= b; i++) values.push(i)\n } else {\n values.push(parseInt(part, 10))\n }\n }\n\n return [...new Set(values)].sort((a, b) => a - b)\n}\n\nfunction getNextCronDate(expression: string, after: Date, timezone: string): Date {\n const fields = expression.trim().split(/\\s+/)\n if (fields.length !== 5) throw new Error(`Invalid cron: ${expression}`)\n\n const minutes = parseCronField(fields[0], 0, 59)\n const hours = parseCronField(fields[1], 0, 23)\n const daysOfMonth = parseCronField(fields[2], 1, 31)\n const months = parseCronField(fields[3], 1, 12)\n const daysOfWeek = parseCronField(fields[4], 0, 6)\n\n // Convert to timezone-aware date\n const fmt = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: timezone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n })\n\n // Start searching from next minute\n const candidate = new Date(after.getTime() + 60_000)\n candidate.setSeconds(0, 0)\n\n // Search up to 1 year ahead\n const limit = new Date(candidate.getTime() + 366 * 24 * 60 * 60 * 1000)\n\n while (candidate < limit) {\n const parts = fmt.formatToParts(candidate)\n const get = (type: string) => parseInt(parts.find((p) => p.type === type)?.value || \"0\", 10)\n\n const m = get(\"minute\")\n const h = get(\"hour\")\n const dom = get(\"day\")\n const mon = get(\"month\")\n const dow = candidate.getDay()\n\n if (\n minutes.includes(m) &&\n hours.includes(h) &&\n daysOfMonth.includes(dom) &&\n months.includes(mon) &&\n daysOfWeek.includes(dow)\n ) {\n return candidate\n }\n\n // Advance by 1 minute\n candidate.setTime(candidate.getTime() + 60_000)\n }\n\n throw new Error(`No next run found for cron \"${expression}\" within 1 year`)\n}\n\nexport class CronScheduler {\n private jobs: Map<string, CronJobState> = new Map()\n private timers: Map<string, ReturnType<typeof setTimeout>> = new Map()\n private registry: AgentRegistry\n private hooks?: HookRegistry\n private runsDir: string\n private running = false\n private log: (...args: unknown[]) => void\n\n constructor(\n config: DaemonConfig,\n registry: AgentRegistry,\n hooks?: HookRegistry,\n log: (...args: unknown[]) => void = console.error.bind(console, \"[cron]\"),\n ) {\n this.registry = registry\n this.hooks = hooks\n this.log = log\n this.runsDir = resolve(process.cwd(), \".agentx/cron/runs\")\n\n for (const [id, def] of Object.entries(config.crons)) {\n this.jobs.set(id, {\n id,\n enabled: def.enabled,\n schedule: def.schedule,\n timezone: def.timezone,\n agent: def.agent,\n prompt: def.prompt,\n timeout: def.timeout,\n model: def.model,\n onError: def.onError,\n consecutiveErrors: 0,\n totalRuns: 0,\n })\n }\n }\n\n async start(): Promise<void> {\n this.running = true\n\n if (!existsSync(this.runsDir)) {\n mkdirSync(this.runsDir, { recursive: true })\n }\n\n for (const [id, job] of this.jobs) {\n if (!job.enabled) {\n this.log(`Job \"${id}\" is disabled, skipping`)\n continue\n }\n this.scheduleNext(id)\n }\n\n this.log(`${this.jobs.size} cron job(s) loaded, ${Array.from(this.jobs.values()).filter((j) => j.enabled).length} enabled`)\n }\n\n async stop(): Promise<void> {\n this.running = false\n for (const timer of this.timers.values()) {\n clearTimeout(timer)\n }\n this.timers.clear()\n }\n\n private scheduleNext(jobId: string): void {\n const job = this.jobs.get(jobId)\n if (!job || !job.enabled || !this.running) return\n\n try {\n const nextRun = getNextCronDate(job.schedule, new Date(), job.timezone)\n job.nextRun = nextRun\n const delay = nextRun.getTime() - Date.now()\n\n this.log(`Job \"${jobId}\" next run: ${nextRun.toISOString()} (in ${Math.round(delay / 1000)}s)`)\n\n const timer = setTimeout(() => this.executeJob(jobId), delay)\n this.timers.set(jobId, timer)\n } catch (e: any) {\n this.log(`Failed to schedule \"${jobId}\": ${e.message}`)\n }\n }\n\n private async executeJob(jobId: string): Promise<void> {\n const job = this.jobs.get(jobId)\n if (!job || !this.running) return\n\n // Pre-hook\n if (this.hooks?.has(\"pre:cron-run\" as any)) {\n const hookResult = await this.hooks.execute(\"pre:cron-run\" as any, {\n event: \"pre:cron-run\" as any,\n jobId,\n agent: job.agent,\n prompt: job.prompt,\n })\n if (hookResult.blocked) {\n this.log(`Job \"${jobId}\" blocked by hook: ${hookResult.message}`)\n this.scheduleNext(jobId)\n return\n }\n }\n\n this.log(`Executing job \"${jobId}\" -> agent \"${job.agent}\"`)\n const startedAt = new Date()\n job.lastRun = startedAt\n job.totalRuns++\n\n try {\n const response = await this.registry.execute({\n message: job.prompt,\n agentId: job.agent,\n context: { channel: \"cron\" },\n })\n\n const result: CronRunResult = {\n jobId,\n startedAt,\n completedAt: new Date(),\n success: !response.error,\n response: response.content,\n error: response.error,\n duration: response.duration || Date.now() - startedAt.getTime(),\n }\n\n if (response.error) {\n job.consecutiveErrors++\n this.log(`Job \"${jobId}\" failed (${job.consecutiveErrors} consecutive): ${response.error}`)\n\n if (job.onError === \"disable\" && job.consecutiveErrors >= 3) {\n job.enabled = false\n this.log(`Job \"${jobId}\" disabled after ${job.consecutiveErrors} consecutive errors`)\n }\n } else {\n job.consecutiveErrors = 0\n this.log(`Job \"${jobId}\" completed in ${result.duration}ms`)\n }\n\n // Log run\n this.logRun(result)\n\n // Post-hook\n if (this.hooks?.has(\"post:cron-run\" as any)) {\n await this.hooks.execute(\"post:cron-run\" as any, {\n event: \"post:cron-run\" as any,\n jobId,\n success: result.success,\n duration: result.duration,\n error: result.error ? new Error(result.error) : undefined,\n })\n }\n } catch (e: any) {\n job.consecutiveErrors++\n this.log(`Job \"${jobId}\" threw: ${e.message}`)\n }\n\n // Schedule next run\n this.scheduleNext(jobId)\n }\n\n private logRun(result: CronRunResult): void {\n try {\n const runDir = resolve(this.runsDir, result.jobId)\n if (!existsSync(runDir)) {\n mkdirSync(runDir, { recursive: true })\n }\n\n const filename = `${result.startedAt.toISOString().replace(/[:.]/g, \"-\")}.json`\n writeFileSync(\n resolve(runDir, filename),\n JSON.stringify(result, null, 2),\n )\n } catch {\n // Don't fail on logging errors\n }\n }\n\n /**\n * List all jobs and their status.\n */\n list(): CronJobState[] {\n return Array.from(this.jobs.values())\n }\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from \"http\"\nimport { loadDaemonConfig, validateWorkspaces, type DaemonConfig } from \"./config\"\nimport { AgentRegistry } from \"@/agents/registry\"\nimport { MessageRouter } from \"@/channels/router\"\nimport { TelegramAdapter } from \"@/channels/telegram\"\nimport { WhatsAppAdapter } from \"@/channels/whatsapp\"\nimport { CronScheduler } from \"@/crons/scheduler\"\nimport { A2AMesh } from \"@/a2a/mesh\"\nimport { HookRegistry, loadHooks } from \"@/hooks\"\n\n// --- AgentX Daemon: the thin orchestration layer ---\n//\n// This is NOT an AI runtime. It's a message router + scheduler + mesh\n// that triggers Claude Code sessions in workspace directories.\n//\n// Each agent = a workspace with .claude/ config\n// agentx just orchestrates WHEN and WHERE Claude Code runs.\n\nexport class AgentXDaemon {\n private config: DaemonConfig\n private registry: AgentRegistry\n private router: MessageRouter\n private cron: CronScheduler\n private mesh?: A2AMesh\n private hooks: HookRegistry\n private httpServer?: ReturnType<typeof createServer>\n private log: (...args: unknown[]) => void\n\n constructor(configPath?: string) {\n this.log = console.error.bind(console, \"[agentx]\")\n\n // Load config\n this.log(\"Loading configuration...\")\n this.config = loadDaemonConfig(configPath)\n\n // Validate\n const warnings = validateWorkspaces(this.config)\n for (const w of warnings) {\n this.log(` ⚠ ${w}`)\n }\n\n // Initialize hooks\n this.hooks = new HookRegistry()\n loadHooks(process.cwd(), this.hooks)\n\n // Initialize agent registry\n this.registry = new AgentRegistry(this.config, this.log)\n\n // Initialize message router\n this.router = new MessageRouter(this.registry, this.config, this.hooks, this.log)\n\n // Initialize cron scheduler\n this.cron = new CronScheduler(this.config, this.registry, this.hooks, this.log)\n\n // Initialize mesh (if enabled)\n if (this.config.mesh.enabled) {\n this.mesh = new A2AMesh(this.config, this.log)\n }\n }\n\n async start(): Promise<void> {\n this.log(\"\")\n this.log(\" ┌─────────────────────────────────────┐\")\n this.log(\" │ agentx daemon │\")\n this.log(\" └─────────────────────────────────────┘\")\n this.log(\"\")\n this.log(` Node: ${this.config.node.name} (${this.config.node.id})`)\n this.log(` Bind: ${this.config.node.bind}`)\n this.log(\"\")\n\n // 1. Start channels\n await this.startChannels()\n\n // 2. Start cron scheduler\n await this.cron.start()\n\n // 3. Start mesh\n if (this.mesh) {\n await this.mesh.start()\n }\n\n // 4. Start HTTP API\n await this.startHttpApi()\n\n // Print agent summary\n this.log(\"\")\n this.log(\" Agents:\")\n for (const agent of this.registry.list()) {\n this.log(` ${agent.id} (${agent.tier}) → ${agent.workspace}`)\n }\n\n // Print cron summary\n const cronJobs = this.cron.list()\n if (cronJobs.length) {\n this.log(\"\")\n this.log(\" Cron Jobs:\")\n for (const job of cronJobs) {\n const status = job.enabled ? \"enabled\" : \"disabled\"\n this.log(` ${job.id} [${status}] → ${job.agent} (${job.schedule})`)\n }\n }\n\n // Print mesh summary\n if (this.mesh) {\n this.log(\"\")\n this.log(\" Mesh Peers:\")\n for (const peer of this.mesh.directory()) {\n const status = peer.healthy ? \"✓\" : \"✗\"\n this.log(` ${status} ${peer.peer} (${peer.peerUrl})`)\n }\n }\n\n this.log(\"\")\n this.log(\" Ready.\")\n this.log(\"\")\n\n // Graceful shutdown\n process.on(\"SIGINT\", () => this.stop())\n process.on(\"SIGTERM\", () => this.stop())\n }\n\n async stop(): Promise<void> {\n this.log(\"Shutting down...\")\n await this.router.stopAll()\n await this.cron.stop()\n if (this.mesh) await this.mesh.stop()\n if (this.httpServer) {\n this.httpServer.close()\n }\n this.log(\"Goodbye.\")\n process.exit(0)\n }\n\n private async startChannels(): Promise<void> {\n // Telegram\n if (this.config.channels.telegram.enabled) {\n const accounts = this.config.channels.telegram.accounts\n if (Object.keys(accounts).length > 0) {\n const telegram = new TelegramAdapter(accounts, this.log)\n this.router.addChannel(telegram)\n this.log(\" Telegram: enabled\")\n }\n }\n\n // WhatsApp\n if (this.config.channels.whatsapp.enabled) {\n const whatsapp = new WhatsAppAdapter(\n {\n sessionDir: this.config.channels.whatsapp.sessionDir,\n agentBinding: this.config.channels.whatsapp.agentBinding,\n },\n this.log,\n )\n this.router.addChannel(whatsapp)\n this.log(\" WhatsApp: enabled (placeholder)\")\n }\n\n await this.router.startAll()\n }\n\n private async startHttpApi(): Promise<void> {\n const [host, portStr] = this.config.node.bind.split(\":\")\n const port = parseInt(portStr || \"18800\", 10)\n\n this.httpServer = createServer(async (req, res) => {\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\")\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, OPTIONS\")\n res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\")\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(204)\n res.end()\n return\n }\n\n await this.handleHttp(req, res)\n })\n\n this.httpServer.listen(port, host || \"127.0.0.1\", () => {\n this.log(` HTTP API: http://${host || \"127.0.0.1\"}:${port}`)\n })\n }\n\n private async handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url || \"/\", `http://${req.headers.host || \"localhost\"}`)\n const path = url.pathname\n\n try {\n switch (`${req.method} ${path}`) {\n case \"GET /health\":\n this.json(res, 200, {\n status: \"ok\",\n node: this.config.node,\n uptime: process.uptime(),\n agents: this.registry.list(),\n crons: this.cron.list().map((j) => ({ id: j.id, enabled: j.enabled, nextRun: j.nextRun })),\n mesh: this.mesh?.directory() || [],\n })\n break\n\n case \"GET /agents\":\n this.json(res, 200, this.registry.list())\n break\n\n case \"GET /crons\":\n this.json(res, 200, this.cron.list())\n break\n\n case \"GET /mesh\":\n this.json(res, 200, this.mesh?.directory() || [])\n break\n\n case \"POST /task\": {\n const body = await readBody(req)\n if (!body.agent || !body.message) {\n this.json(res, 400, { error: \"Missing: agent, message\" })\n return\n }\n const response = await this.registry.execute({\n agentId: body.agent as string,\n message: body.message as string,\n context: body.context as any,\n })\n this.json(res, response.error ? 500 : 200, response)\n break\n }\n\n case \"POST /mesh/task\": {\n const body = await readBody(req)\n if (!body.peer || !body.message) {\n this.json(res, 400, { error: \"Missing: peer, message\" })\n return\n }\n if (!this.mesh) {\n this.json(res, 400, { error: \"Mesh not enabled\" })\n return\n }\n const result = await this.mesh.sendTask(body.peer as string, body.message as string)\n this.json(res, 200, { response: result })\n break\n }\n\n // A2A agent card discovery\n case \"GET /.well-known/agent-card.json\":\n this.json(res, 200, {\n name: this.config.node.name,\n description: `AgentX daemon node \"${this.config.node.name}\"`,\n url: `http://${this.config.node.bind}`,\n version: \"1.0.0\",\n capabilities: {\n streaming: false,\n pushNotifications: false,\n stateTransitionHistory: false,\n },\n skills: this.registry.list().map((a) => ({\n id: a.id,\n name: a.name,\n description: `Agent \"${a.name}\" (${a.tier})`,\n tags: [a.tier],\n })),\n defaultInputModes: [\"text\"],\n defaultOutputModes: [\"text\"],\n })\n break\n\n default:\n this.json(res, 404, {\n error: \"Not found\",\n endpoints: [\n \"GET /health\",\n \"GET /agents\",\n \"GET /crons\",\n \"GET /mesh\",\n \"POST /task { agent, message, context? }\",\n \"POST /mesh/task { peer, message }\",\n \"GET /.well-known/agent-card.json\",\n ],\n })\n }\n } catch (e: any) {\n this.json(res, 500, { error: e.message })\n }\n }\n\n private json(res: ServerResponse, status: number, data: unknown): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" })\n res.end(JSON.stringify(data, null, 2))\n }\n}\n\nasync function readBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let body = \"\"\n req.on(\"data\", (chunk: Buffer) => (body += chunk.toString()))\n req.on(\"end\", () => {\n try {\n resolve(body ? JSON.parse(body) : {})\n } catch {\n resolve({})\n }\n })\n req.on(\"error\", reject)\n })\n}\n","import { logger } from \"@/utils/logger\"\n\nexport function handleError(error: unknown) {\n if (typeof error === \"string\") {\n logger.error(error)\n process.exit(1)\n }\n\n if (error instanceof Error) {\n logger.error(error.message)\n process.exit(1)\n }\n\n logger.error(\"Something went wrong. Please try again.\")\n process.exit(1)\n}\n","import path from \"path\"\nimport fs from \"fs-extra\"\nimport { type PackageJson } from \"type-fest\"\n\nexport function getPackageInfo() {\n const packageJsonPath = path.join(\"package.json\")\n\n return fs.readJSONSync(packageJsonPath) as PackageJson\n}\n"],"mappings":"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","names":["execa","existsSync","fs","path","fetch","installSkillPackage","packageId","cwd","parts","owner","repo","specificSkill","skillArg","execa","logger","skillsDir","path","existsSync","loadInstalledSkills","altDir","fetchFromGitHub","skills","treeUrl","response","fetch","skillFiles","item","specific","f","skill","fetchAndSaveSkill","file","error","filePath","rawUrl","content","parseSkillContent","skillDir","localDir","fs","dir","fg","fullPath","generateSkillMd","name","description","instructions","tags","globs","frontmatter","tag","glob","listInstalledSkills","loadLocalSkills","generateSkill","provider","name","description","techStack","options","messages","formatTechStack","skillContent","skill","frontmatterMatch","existsSync","fs","path","DEFAULT_CONFIG","EnhanceEngine","cwd","memory","config","result","newSkills","insights","prefInsights","eligiblePatterns","p","created","skillsDir","path","pattern","skillName","patternToSkillName","skillPath","existsSync","content","fs","recentSuccesses","e","provider","createProvider","techStack","detectTechStack","messages","formatTechStack","failures","errorGroups","f","key","group","error","entries","stats","highConfidence","Pipeline","name","fn","req","res","context","index","next","error","m","createServer","DEFAULT_CONFIG","AgentXRuntime","config","Memory","HealEngine","EnhanceEngine","pipeline","Pipeline","createServer","req","res","url","method","pathname","error","body","readBody","pipelineReq","result","context","createAgentContext","m","memory","ctx","next","memoryContext","generate","f","healEngine","healResult","entryId","l","enhanceEngine","insight","status","data","resolve","reject","chunk","SERVER_INFO","PROTOCOL_VERSION","CAPABILITIES","TOOLS","handleToolCall","name","args","cwd","task","outputType","outputDir","result","generate","summary","f","context","createAgentContext","info","m","s","formatTechStack","skills","loadLocalSkills","matches","matchSkillsToTask","resolveOutputType","startMcpServer","log","buffer","chunk","headerEnd","contentLengthMatch","newlineIdx","line","msg","handleMessage","e","contentLength","bodyStart","bodyEnd","body","send","message","header","method","id","params","toolName","toolArgs","error","execa","GitManager","cwd","lines","branch","staged","modified","untracked","deleted","line","indexStatus","workStatus","file","result","files","additions","deletions","path","status","count","hash","shortHash","message","author","date","filesMatch","filesChanged","name","args","provider","diff","fileChanges","match","existsSync","mkdirSync","readFileSync","readdirSync","writeFileSync","path","os","SESSIONS_DIR","ensureSessionsDir","createSession","cwd","generateId","saveSession","session","filePath","loadSession","id","loadLatestSession","files","f","latest","file","listSessions","sessions","a","b","chalk","writeFileSync","path","chalk","renderBanner","version","sessionId","renderFiles","result","file","err","renderCost","tokensUsed","cost","renderStreamChunk","text","renderHelp","chalk","renderGitStatus","status","renderCostBreakdown","summary","model","usage","step","renderPlan","files","file","icon","prompts","commands","registerCommand","name","handler","getCommand","isCommand","input","parseCommand","trimmed","spaceIdx","renderHelp","_args","ctx","chalk","saveSession","args","session","loadSession","logger","sessions","listSessions","sessionId","s","messages","summary","globalTracker","renderCostBreakdown","renderCost","markdown","exportSession","filename","filePath","path","writeFileSync","files","f","memory","MemoryHierarchy","stats","prefs","patterns","recent","p","r","status","error","_ctx","PERMISSION_MODES","globalPermissions","current","gm","GitManager","generatedFiles","message","provider","createProvider","result","diff","renderGitStatus","createInterface","chalk","ora","ReplEngine","options","loaded","loadSession","logger","createSession","latest","loadLatestSession","renderBanner","chalk","createInterface","line","input","isCommand","error","saveSession","renderCost","name","args","parseCommand","handler","getCommand","ctx","newSession","spinner","ora","sessionMessages","m","generateOptions","result","streaming","event","generateStream","renderStreamChunk","globalPermissions","renderPlan","f","renderFiles","createServer","A2A_ERRORS","DEFAULT_CONFIG","A2AServer","config","createServer","req","res","url","method","pathname","body","readBody","error","request","A2A_ERRORS","rpc","params","rpcId","taskId","message","taskText","p","task","result","generate","artifacts","filePath","i","agentMessage","sendSSE","update","textContent","event","generateStream","fileArtifacts","artifact","status","data","response","resolve","reject","chunk","A2AClient","baseUrl","token","res","text","metadata","response","body","reader","decoder","buffer","done","value","lines","line","data","taskId","method","params","h","A2AMesh","config","log","peer","A2AClient","interval","results","name","state","healthy","p","timeout","controller","timer","card","e","peerName","text","agentId","agent","url","headers","res","data","skillId","a","z","readFileSync","existsSync","resolve","loadDotEnv","dir","envPath","content","line","trimmed","eqIdx","key","value","providerConfigSchema","agentConfigSchema","telegramAccountSchema","channelsConfigSchema","cronJobSchema","meshPeerSchema","meshConfigSchema","daemonConfigSchema","expandEnvVars","obj","_match","name","result","loadDaemonConfig","configPath","paths","raw","foundPath","p","parsed","e","expanded","issues","i","validateWorkspaces","config","warnings","id","agent","claudeDir","providerName","providerConfig","cron","account","execa","execFile","buildPrompt","agent","task","historyContext","parts","ctx","envLines","peer","handle","role","buildClaudeArgs","prompt","streaming","resumeSessionId","args","extractSessionId","stderr","executeClaudeCode","start","stdout","resolve","reject","error","capturedSessionId","executeClaudeCodeStreaming","onDelta","fullText","proc","lineBuffer","chunk","lines","line","event","block","delta","resultText","result","executeSdk","apiKey","sdk","query","content","q","message","executeOrchestrator","generate","providerName","executeTask","providers","readFileSync","writeFileSync","mkdirSync","existsSync","resolve","MAX_HISTORY_CHARS","MAX_MESSAGES","SessionStore","baseDir","agentId","channel","chatId","day","key","safe","file","data","session","senderName","content","claudeSessionId","lines","msg","time","totalChars","sum","m","removed","AgentRegistry","config","log","SessionStore","id","def","text","lower","bestId","bestLen","state","mention","mentionLower","found","agentId","channel","agent","m","task","peers","myHandle","onDelta","chatId","senderName","resumeSessionId","historyContext","response","executeTask","error","s","MessageRouter","registry","config","hooks","log","adapter","msg","name","hookResult","agentId","boundAccount","chatId","agentName","replyAccountId","typingTimer","canStream","sentMessageId","lastEditTime","onDelta","_delta","fullText","now","preview","response","errorText","responseText","sentResponseId","e","originalMsg","sourceAgentId","responseMessageId","id","def","m","targetAccountId","messageId","text","parseMode","accountId","emoji","sendTyping","account","mentionAgent","SPECIAL","esc","text","escCode","markdownToTelegramV2","md","lines","result","inCodeBlock","codeBlockLang","codeBlockLines","i","line","code","headerMatch","escInline","content","convertInline","ulMatch","indent","olMatch","num","codeSpans","processed","_match","idx","mentions","username","links","label","url","_m","t","escPlainSegments","part","TelegramAdapter","accounts","log","handler","accountId","config","me","e","chatId","token","msg","maxLen","text","formatted","markdownToTelegramV2","params","result","messageId","parseMode","trimmed","emoji","offset","updates","update","incoming","r","method","url","res","WhatsAppAdapter","config","log","handler","msg","writeFileSync","mkdirSync","existsSync","resolve","parseCronField","field","min","max","values","part","i","range","stepStr","step","start","a","b","getNextCronDate","expression","after","timezone","fields","minutes","hours","daysOfMonth","months","daysOfWeek","fmt","candidate","limit","parts","get","type","p","m","h","dom","mon","dow","CronScheduler","config","registry","hooks","log","id","def","job","j","timer","jobId","nextRun","delay","e","hookResult","startedAt","response","result","runDir","filename","createServer","AgentXDaemon","configPath","loadDaemonConfig","warnings","validateWorkspaces","w","HookRegistry","loadHooks","AgentRegistry","MessageRouter","CronScheduler","A2AMesh","agent","cronJobs","job","status","peer","accounts","telegram","TelegramAdapter","whatsapp","WhatsAppAdapter","host","portStr","port","createServer","req","res","path","j","body","readBody","response","result","a","e","data","resolve","reject","chunk","handleError","error","logger","path","fs","getPackageInfo","packageJsonPath"]}