@openacp/cli 0.2.4 → 0.2.11

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../packages/core/src/streams.ts","../../packages/core/src/stderr-capture.ts","../../packages/core/src/agent-instance.ts","../../packages/core/src/agent-manager.ts","../../packages/core/src/session.ts","../../packages/core/src/session-manager.ts","../../packages/core/src/notification.ts","../../packages/core/src/core.ts"],"sourcesContent":["import type { Writable, Readable } from 'node:stream'\n\nexport function nodeToWebWritable(nodeStream: Writable): WritableStream<Uint8Array> {\n return new WritableStream<Uint8Array>({\n write(chunk) {\n return new Promise<void>((resolve, reject) => {\n nodeStream.write(Buffer.from(chunk), (err) => {\n if (err) reject(err)\n else resolve()\n })\n })\n },\n })\n}\n\nexport function nodeToWebReadable(nodeStream: Readable): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n nodeStream.on('data', (chunk: Buffer) => {\n controller.enqueue(new Uint8Array(chunk))\n })\n nodeStream.on('end', () => controller.close())\n nodeStream.on('error', (err) => controller.error(err))\n },\n })\n}\n","export class StderrCapture {\n private lines: string[] = []\n\n constructor(private maxLines: number = 50) {}\n\n append(chunk: string): void {\n this.lines.push(...chunk.split('\\n').filter(Boolean))\n if (this.lines.length > this.maxLines) {\n this.lines = this.lines.slice(-this.maxLines)\n }\n }\n\n getLastLines(): string {\n return this.lines.join('\\n')\n }\n}\n","import { spawn, execSync, type ChildProcess } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { randomUUID } from 'node:crypto'\nimport { ClientSideConnection, ndJsonStream } from '@agentclientprotocol/sdk'\nimport type { Agent, Client, PromptResponse, PermissionOption as SdkPermissionOption } from '@agentclientprotocol/sdk'\nimport { nodeToWebWritable, nodeToWebReadable } from './streams.js'\nimport { StderrCapture } from './stderr-capture.js'\nimport type { AgentDefinition, AgentEvent, PermissionRequest } from './types.js'\nimport { log } from './log.js'\n\n/** Resolve an agent command to a directly executable form (avoids shell wrappers) */\nfunction resolveAgentCommand(cmd: string): { command: string; args: string[] } {\n // 1. Check local node_modules for the package's actual JS entry point\n const packageDirs = [\n path.resolve(process.cwd(), 'node_modules', '@zed-industries', cmd, 'dist', 'index.js'),\n path.resolve(process.cwd(), 'node_modules', cmd, 'dist', 'index.js'),\n ]\n for (const jsPath of packageDirs) {\n if (fs.existsSync(jsPath)) {\n return { command: process.execPath, args: [jsPath] }\n }\n }\n\n // 2. Check local .bin — if it's a JS file with shebang, run with node directly\n const localBin = path.resolve(process.cwd(), 'node_modules', '.bin', cmd)\n if (fs.existsSync(localBin)) {\n const content = fs.readFileSync(localBin, 'utf-8')\n if (content.startsWith('#!/usr/bin/env node')) {\n return { command: process.execPath, args: [localBin] }\n }\n // Shell wrapper — try to find the target JS file\n const match = content.match(/\"([^\"]+\\.js)\"/)\n if (match) {\n const target = path.resolve(path.dirname(localBin), match[1])\n if (fs.existsSync(target)) {\n return { command: process.execPath, args: [target] }\n }\n }\n }\n\n // 3. Try resolving from PATH using which\n try {\n const fullPath = execSync(`which ${cmd}`, { encoding: 'utf-8' }).trim()\n if (fullPath) {\n const content = fs.readFileSync(fullPath, 'utf-8')\n if (content.startsWith('#!/usr/bin/env node')) {\n return { command: process.execPath, args: [fullPath] }\n }\n }\n } catch {\n // which failed\n }\n\n // 4. Fallback: use command as-is\n return { command: cmd, args: [] }\n}\n\ninterface TerminalState {\n process: ChildProcess\n output: string\n exitStatus: { exitCode: number | null; signal: string | null } | null\n}\n\nexport class AgentInstance {\n private connection!: ClientSideConnection\n private child!: ChildProcess\n private stderrCapture!: StderrCapture\n private terminals: Map<string, TerminalState> = new Map()\n\n sessionId!: string\n agentName: string\n\n // Callbacks — set by core when wiring events\n onSessionUpdate: (event: AgentEvent) => void = () => {}\n onPermissionRequest: (request: PermissionRequest) => Promise<string> = async () => ''\n\n private constructor(agentName: string) {\n this.agentName = agentName\n }\n\n static async spawn(agentDef: AgentDefinition, workingDirectory: string): Promise<AgentInstance> {\n const instance = new AgentInstance(agentDef.name)\n\n // 1. Resolve command: find the actual JS entry point to avoid shell wrappers\n const resolved = resolveAgentCommand(agentDef.command)\n log.debug(`Spawning agent \"${agentDef.name}\" → ${resolved.command} ${resolved.args.join(' ')}`)\n\n // Spawn subprocess\n instance.child = spawn(resolved.command, [...resolved.args, ...agentDef.args], {\n stdio: ['pipe', 'pipe', 'pipe'],\n cwd: workingDirectory,\n env: { ...process.env, ...agentDef.env },\n })\n\n // 2. Handle spawn errors (e.g., command not found)\n await new Promise<void>((resolve, reject) => {\n instance.child.on('error', (err) => {\n reject(new Error(`Failed to spawn agent \"${agentDef.name}\": ${err.message}. Is \"${agentDef.command}\" installed?`))\n })\n instance.child.on('spawn', () => resolve())\n })\n\n // 3. Capture stderr\n instance.stderrCapture = new StderrCapture(50)\n instance.child.stderr!.on('data', (chunk: Buffer) => {\n instance.stderrCapture.append(chunk.toString())\n })\n\n // 3. Create ACP stream\n const toAgent = nodeToWebWritable(instance.child.stdin!)\n const fromAgent = nodeToWebReadable(instance.child.stdout!)\n const stream = ndJsonStream(toAgent, fromAgent)\n\n // 4. Create ClientSideConnection\n instance.connection = new ClientSideConnection(\n (_agent: Agent): Client => instance.createClient(_agent),\n stream,\n )\n\n // 5. ACP handshake\n await instance.connection.initialize({\n protocolVersion: 1,\n clientCapabilities: {\n fs: { readTextFile: true, writeTextFile: true },\n terminal: true,\n },\n })\n\n // 6. Create session\n const response = await instance.connection.newSession({\n cwd: workingDirectory,\n mcpServers: [],\n })\n instance.sessionId = response.sessionId\n\n // 7. Crash detection\n instance.child.on('exit', (code, signal) => {\n if (code !== 0 && code !== null) {\n const stderr = instance.stderrCapture.getLastLines()\n instance.onSessionUpdate({\n type: 'error',\n message: `Agent crashed (exit code ${code})\\n${stderr}`,\n })\n }\n })\n\n instance.connection.closed.then(() => {\n // Connection closed — may be normal shutdown or crash\n log.debug('ACP connection closed for', instance.agentName)\n })\n\n log.info(`Agent \"${agentDef.name}\" spawned with session ${response.sessionId}`)\n return instance\n }\n\n // createClient — implemented in Task 6b\n private createClient(_agent: Agent): Client {\n const self = this\n const MAX_OUTPUT_BYTES = 1024 * 1024 // 1MB cap\n\n return {\n // ── Session updates ──────────────────────────────────────────────────\n async sessionUpdate(params) {\n const update = params.update\n let event: AgentEvent | null = null\n\n switch (update.sessionUpdate) {\n case 'agent_message_chunk':\n if (update.content.type === 'text') {\n event = { type: 'text', content: update.content.text }\n }\n break\n case 'agent_thought_chunk':\n if (update.content.type === 'text') {\n event = { type: 'thought', content: update.content.text }\n }\n break\n case 'tool_call':\n event = {\n type: 'tool_call',\n id: update.toolCallId,\n name: update.title,\n kind: update.kind ?? undefined,\n status: update.status ?? 'pending',\n content: update.content ?? undefined,\n }\n break\n case 'tool_call_update':\n event = {\n type: 'tool_update',\n id: update.toolCallId,\n status: update.status ?? 'pending',\n content: update.content ?? undefined,\n }\n break\n case 'plan':\n event = { type: 'plan', entries: update.entries }\n break\n case 'usage_update':\n event = {\n type: 'usage',\n tokensUsed: update.used,\n contextSize: update.size,\n cost: update.cost ?? undefined,\n }\n break\n case 'available_commands_update':\n event = { type: 'commands_update', commands: update.availableCommands }\n break\n default:\n // Unknown update type — ignore\n return\n }\n\n if (event !== null) {\n self.onSessionUpdate(event)\n }\n },\n\n // ── Permission requests ──────────────────────────────────────────────\n async requestPermission(params) {\n const permissionRequest: PermissionRequest = {\n id: params.toolCall.toolCallId,\n description: params.toolCall.title ?? params.toolCall.toolCallId,\n options: params.options.map((opt: SdkPermissionOption) => ({\n id: opt.optionId,\n label: opt.name,\n isAllow: opt.kind === 'allow_once' || opt.kind === 'allow_always',\n })),\n }\n\n const selectedOptionId = await self.onPermissionRequest(permissionRequest)\n return {\n outcome: { outcome: 'selected' as const, optionId: selectedOptionId },\n }\n },\n\n // ── File operations ──────────────────────────────────────────────────\n async readTextFile(params) {\n const content = await fs.promises.readFile(params.path, 'utf-8')\n return { content }\n },\n\n async writeTextFile(params) {\n await fs.promises.mkdir(path.dirname(params.path), { recursive: true })\n await fs.promises.writeFile(params.path, params.content, 'utf-8')\n return {}\n },\n\n // ── Terminal operations ──────────────────────────────────────────────\n async createTerminal(params) {\n const terminalId = randomUUID()\n const args = params.args ?? []\n const env: Record<string, string> = {}\n for (const ev of params.env ?? []) {\n env[ev.name] = ev.value\n }\n\n const childProcess = spawn(params.command, args, {\n cwd: params.cwd ?? undefined,\n env: { ...process.env, ...env },\n shell: false,\n })\n\n const state: TerminalState = {\n process: childProcess,\n output: '',\n exitStatus: null,\n }\n self.terminals.set(terminalId, state)\n\n const outputByteLimit = params.outputByteLimit ?? MAX_OUTPUT_BYTES\n\n const appendOutput = (chunk: string) => {\n state.output += chunk\n // Truncate from the beginning if over limit\n const bytes = Buffer.byteLength(state.output, 'utf-8')\n if (bytes > outputByteLimit) {\n // Find truncation point at character boundary\n const excess = bytes - outputByteLimit\n state.output = state.output.slice(excess)\n }\n }\n\n childProcess.stdout?.on('data', (chunk: Buffer) => appendOutput(chunk.toString()))\n childProcess.stderr?.on('data', (chunk: Buffer) => appendOutput(chunk.toString()))\n\n childProcess.on('exit', (code, signal) => {\n state.exitStatus = { exitCode: code, signal }\n })\n\n return { terminalId }\n },\n\n async terminalOutput(params) {\n const state = self.terminals.get(params.terminalId)\n if (!state) {\n throw new Error(`Terminal not found: ${params.terminalId}`)\n }\n return {\n output: state.output,\n truncated: false,\n exitStatus: state.exitStatus\n ? { exitCode: state.exitStatus.exitCode, signal: state.exitStatus.signal }\n : undefined,\n }\n },\n\n async waitForTerminalExit(params) {\n const state = self.terminals.get(params.terminalId)\n if (!state) {\n throw new Error(`Terminal not found: ${params.terminalId}`)\n }\n if (state.exitStatus !== null) {\n return { exitCode: state.exitStatus.exitCode, signal: state.exitStatus.signal }\n }\n return new Promise((resolve) => {\n state.process.on('exit', (code, signal) => {\n resolve({ exitCode: code, signal })\n })\n })\n },\n\n async killTerminal(params) {\n const state = self.terminals.get(params.terminalId)\n if (!state) {\n throw new Error(`Terminal not found: ${params.terminalId}`)\n }\n state.process.kill('SIGTERM')\n return {}\n },\n\n async releaseTerminal(params) {\n const state = self.terminals.get(params.terminalId)\n if (!state) {\n return\n }\n state.process.kill('SIGKILL')\n self.terminals.delete(params.terminalId)\n },\n }\n }\n\n async prompt(text: string): Promise<PromptResponse> {\n return this.connection.prompt({\n sessionId: this.sessionId,\n prompt: [{ type: 'text', text }],\n })\n }\n\n async cancel(): Promise<void> {\n await this.connection.cancel({ sessionId: this.sessionId })\n }\n\n async destroy(): Promise<void> {\n // Cleanup terminals\n for (const [, t] of this.terminals) {\n t.process.kill('SIGKILL')\n }\n this.terminals.clear()\n\n // Kill agent subprocess\n this.child.kill('SIGTERM')\n setTimeout(() => {\n if (!this.child.killed) this.child.kill('SIGKILL')\n }, 10_000)\n }\n}\n","import type { Config } from './config.js'\nimport type { AgentDefinition } from './types.js'\nimport { AgentInstance } from './agent-instance.js'\n\nexport class AgentManager {\n constructor(private config: Config) {}\n\n getAvailableAgents(): AgentDefinition[] {\n return Object.entries(this.config.agents).map(([name, cfg]) => ({\n name,\n command: cfg.command,\n args: cfg.args,\n workingDirectory: cfg.workingDirectory,\n env: cfg.env,\n }))\n }\n\n getAgent(name: string): AgentDefinition | undefined {\n const cfg = this.config.agents[name]\n if (!cfg) return undefined\n return { name, ...cfg }\n }\n\n async spawn(agentName: string, workingDirectory: string): Promise<AgentInstance> {\n const agentDef = this.getAgent(agentName)\n if (!agentDef) throw new Error(`Agent \"${agentName}\" not found in config`)\n return AgentInstance.spawn(agentDef, workingDirectory)\n }\n}\n","import { nanoid } from 'nanoid'\nimport type { AgentInstance } from './agent-instance.js'\nimport type { ChannelAdapter } from './channel.js'\nimport type { SessionStatus } from './types.js'\nimport { log } from './log.js'\n\nexport class Session {\n id: string\n channelId: string\n threadId: string = ''\n agentName: string\n workingDirectory: string\n agentInstance: AgentInstance\n status: SessionStatus = 'initializing'\n name?: string\n promptQueue: string[] = []\n promptRunning: boolean = false\n createdAt: Date = new Date()\n adapter?: ChannelAdapter // Set by wireSessionEvents for renaming\n pendingPermission?: { requestId: string; resolve: (optionId: string) => void }\n\n constructor(opts: {\n id?: string\n channelId: string\n agentName: string\n workingDirectory: string\n agentInstance: AgentInstance\n }) {\n this.id = opts.id || nanoid(12)\n this.channelId = opts.channelId\n this.agentName = opts.agentName\n this.workingDirectory = opts.workingDirectory\n this.agentInstance = opts.agentInstance\n }\n\n async enqueuePrompt(text: string): Promise<void> {\n if (this.promptRunning) {\n this.promptQueue.push(text)\n log.debug(`Prompt queued for session ${this.id} (${this.promptQueue.length} in queue)`)\n return\n }\n await this.runPrompt(text)\n }\n\n private async runPrompt(text: string): Promise<void> {\n this.promptRunning = true\n this.status = 'active'\n\n try {\n await this.agentInstance.prompt(text)\n\n // Auto-name after first user prompt\n if (!this.name) {\n await this.autoName()\n }\n } catch (err) {\n this.status = 'error'\n log.error(`Prompt failed for session ${this.id}:`, err)\n } finally {\n this.promptRunning = false\n\n // Process next queued prompt\n if (this.promptQueue.length > 0) {\n const next = this.promptQueue.shift()!\n await this.runPrompt(next)\n }\n }\n }\n\n // NOTE: This injects a summary prompt into the agent's conversation history.\n // Known Phase 1 limitation — the agent sees this prompt in its context.\n private async autoName(): Promise<void> {\n let title = ''\n const prevHandler = this.agentInstance.onSessionUpdate\n this.agentInstance.onSessionUpdate = (event) => {\n if (event.type === 'text') title += event.content\n }\n\n try {\n await this.agentInstance.prompt(\n 'Summarize this conversation in max 5 words for a topic title. Reply ONLY with the title, nothing else.'\n )\n this.name = title.trim().slice(0, 50)\n\n // Rename the topic on the channel\n if (this.adapter && this.name) {\n await this.adapter.renameSessionThread(this.id, this.name)\n }\n } catch {\n this.name = `Session ${this.id.slice(0, 6)}`\n } finally {\n this.agentInstance.onSessionUpdate = prevHandler\n }\n }\n\n async cancel(): Promise<void> {\n this.status = 'cancelled'\n await this.agentInstance.cancel()\n }\n\n async destroy(): Promise<void> {\n await this.agentInstance.destroy()\n }\n}\n","import type { AgentManager } from './agent-manager.js'\nimport { Session } from './session.js'\n\nexport class SessionManager {\n private sessions: Map<string, Session> = new Map()\n\n async createSession(\n channelId: string,\n agentName: string,\n workingDirectory: string,\n agentManager: AgentManager,\n ): Promise<Session> {\n const agentInstance = await agentManager.spawn(agentName, workingDirectory)\n const session = new Session({ channelId, agentName, workingDirectory, agentInstance })\n this.sessions.set(session.id, session)\n return session\n }\n\n getSession(sessionId: string): Session | undefined {\n return this.sessions.get(sessionId)\n }\n\n getSessionByThread(channelId: string, threadId: string): Session | undefined {\n for (const session of this.sessions.values()) {\n if (session.channelId === channelId && session.threadId === threadId) {\n return session\n }\n }\n return undefined\n }\n\n async cancelSession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId)\n if (session) await session.cancel()\n }\n\n listSessions(channelId?: string): Session[] {\n const all = Array.from(this.sessions.values())\n if (channelId) return all.filter(s => s.channelId === channelId)\n return all\n }\n\n async destroyAll(): Promise<void> {\n for (const session of this.sessions.values()) {\n await session.destroy()\n }\n this.sessions.clear()\n }\n}\n","import type { ChannelAdapter } from './channel.js'\nimport type { NotificationMessage } from './types.js'\n\nexport class NotificationManager {\n constructor(private adapters: Map<string, ChannelAdapter>) {}\n\n async notify(channelId: string, notification: NotificationMessage): Promise<void> {\n const adapter = this.adapters.get(channelId)\n if (adapter) {\n await adapter.sendNotification(notification)\n }\n }\n\n async notifyAll(notification: NotificationMessage): Promise<void> {\n for (const adapter of this.adapters.values()) {\n await adapter.sendNotification(notification)\n }\n }\n}\n","import { ConfigManager } from './config.js'\nimport { AgentManager } from './agent-manager.js'\nimport { SessionManager } from './session-manager.js'\nimport { NotificationManager } from './notification.js'\nimport { ChannelAdapter } from './channel.js'\nimport { Session } from './session.js'\nimport type { IncomingMessage, AgentEvent, OutgoingMessage, PermissionRequest } from './types.js'\nimport { log } from './log.js'\n\nexport class OpenACPCore {\n configManager: ConfigManager\n agentManager: AgentManager\n sessionManager: SessionManager\n notificationManager: NotificationManager\n adapters: Map<string, ChannelAdapter> = new Map()\n\n constructor(configManager: ConfigManager) {\n this.configManager = configManager\n const config = configManager.get()\n this.agentManager = new AgentManager(config)\n this.sessionManager = new SessionManager()\n this.notificationManager = new NotificationManager(this.adapters)\n }\n\n registerAdapter(name: string, adapter: ChannelAdapter): void {\n this.adapters.set(name, adapter)\n }\n\n async start(): Promise<void> {\n for (const adapter of this.adapters.values()) {\n await adapter.start()\n }\n }\n\n async stop(): Promise<void> {\n // 1. Notify users\n try {\n await this.notificationManager.notifyAll({\n sessionId: 'system',\n type: 'error',\n summary: 'OpenACP is shutting down',\n })\n } catch { /* best effort */ }\n\n // 2. Destroy all sessions\n await this.sessionManager.destroyAll()\n\n // 3. Stop adapters\n for (const adapter of this.adapters.values()) {\n await adapter.stop()\n }\n }\n\n // --- Message Routing ---\n\n async handleMessage(message: IncomingMessage): Promise<void> {\n const config = this.configManager.get()\n\n // Security: check allowed user IDs\n if (config.security.allowedUserIds.length > 0) {\n if (!config.security.allowedUserIds.includes(message.userId)) return\n }\n\n // Check concurrent session limit\n const activeSessions = this.sessionManager.listSessions()\n .filter(s => s.status === 'active' || s.status === 'initializing')\n if (activeSessions.length >= config.security.maxConcurrentSessions) {\n const adapter = this.adapters.get(message.channelId)\n if (adapter) {\n await adapter.sendMessage('system', {\n type: 'error',\n text: `Max concurrent sessions (${config.security.maxConcurrentSessions}) reached. Cancel a session first.`,\n })\n }\n return\n }\n\n // Find session by thread\n const session = this.sessionManager.getSessionByThread(message.channelId, message.threadId)\n if (!session) return\n\n // Forward to session\n await session.enqueuePrompt(message.text)\n }\n\n async handleNewSession(\n channelId: string,\n agentName?: string,\n workspacePath?: string,\n ): Promise<Session> {\n const config = this.configManager.get()\n const resolvedAgent = agentName || config.defaultAgent\n const resolvedWorkspace = this.configManager.resolveWorkspace(\n workspacePath || config.agents[resolvedAgent]?.workingDirectory\n )\n\n const session = await this.sessionManager.createSession(\n channelId, resolvedAgent, resolvedWorkspace, this.agentManager\n )\n\n // Wire events\n const adapter = this.adapters.get(channelId)\n if (adapter) {\n this.wireSessionEvents(session, adapter)\n }\n\n return session\n }\n\n async handleNewChat(\n channelId: string,\n currentThreadId: string,\n ): Promise<Session | null> {\n const currentSession = this.sessionManager.getSessionByThread(channelId, currentThreadId)\n if (!currentSession) return null\n\n return this.handleNewSession(\n channelId,\n currentSession.agentName,\n currentSession.workingDirectory,\n )\n }\n\n // --- Event Wiring ---\n\n private toOutgoingMessage(event: AgentEvent): OutgoingMessage {\n switch (event.type) {\n case 'text':\n return { type: 'text', text: event.content }\n case 'thought':\n return { type: 'thought', text: event.content }\n case 'tool_call':\n return { type: 'tool_call', text: event.name, metadata: { id: event.id, kind: event.kind, status: event.status, content: event.content, locations: event.locations } }\n case 'tool_update':\n return { type: 'tool_update', text: '', metadata: { id: event.id, status: event.status, content: event.content } }\n case 'plan':\n return { type: 'plan', text: '', metadata: { entries: event.entries } }\n case 'usage':\n return { type: 'usage', text: '', metadata: { tokensUsed: event.tokensUsed, contextSize: event.contextSize, cost: event.cost } }\n case 'commands_update':\n // Log but don't surface to user (Phase 3 feature)\n log.debug('Commands update:', event.commands)\n return { type: 'text', text: '' } // no-op for now\n default:\n return { type: 'text', text: '' }\n }\n }\n\n // Public — adapters call this for assistant session wiring\n wireSessionEvents(session: Session, adapter: ChannelAdapter): void {\n // Set adapter reference for autoName → renameSessionThread\n session.adapter = adapter\n\n session.agentInstance.onSessionUpdate = (event: AgentEvent) => {\n switch (event.type) {\n case 'text':\n case 'thought':\n case 'tool_call':\n case 'tool_update':\n case 'plan':\n case 'usage':\n adapter.sendMessage(session.id, this.toOutgoingMessage(event))\n break\n\n case 'session_end':\n session.status = 'finished'\n adapter.sendMessage(session.id, { type: 'session_end', text: `Done (${event.reason})` })\n this.notificationManager.notify(session.channelId, {\n sessionId: session.id,\n sessionName: session.name,\n type: 'completed',\n summary: `Session \"${session.name || session.id}\" completed`,\n })\n break\n\n case 'error':\n adapter.sendMessage(session.id, { type: 'error', text: event.message })\n this.notificationManager.notify(session.channelId, {\n sessionId: session.id,\n sessionName: session.name,\n type: 'error',\n summary: event.message,\n })\n break\n\n case 'commands_update':\n log.debug('Commands available:', event.commands)\n break\n }\n }\n\n session.agentInstance.onPermissionRequest = async (request: PermissionRequest) => {\n // Set pending BEFORE sending UI to avoid race condition\n const promise = new Promise<string>((resolve) => {\n session.pendingPermission = { requestId: request.id, resolve }\n })\n\n // Send permission UI to session topic (notification is sent by adapter)\n await adapter.sendPermissionRequest(session.id, request)\n\n // Wait for user response — adapter resolves this promise\n return promise\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,38 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
- }) : x)(function(x) {
10
- if (typeof require !== "undefined") return require.apply(this, arguments);
11
- throw Error('Dynamic require of "' + x + '" is not supported');
12
- });
13
- var __commonJS = (cb, mod) => function __require2() {
14
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
- };
16
- var __copyProps = (to, from, except, desc) => {
17
- if (from && typeof from === "object" || typeof from === "function") {
18
- for (let key of __getOwnPropNames(from))
19
- if (!__hasOwnProp.call(to, key) && key !== except)
20
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
- }
22
- return to;
23
- };
24
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
- // If the importer is in node compatibility mode or this is not an ESM
26
- // file that has been converted to a CommonJS file using a Babel-
27
- // compatible transform (i.e. "__esModule" has not been set), then set
28
- // "default" to the CommonJS "module.exports" for node compatibility.
29
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
- mod
31
- ));
32
-
33
- export {
34
- __require,
35
- __commonJS,
36
- __toESM
37
- };
38
- //# sourceMappingURL=chunk-LZOMFHX3.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../packages/core/src/log.ts","../../packages/core/src/config.ts","../../packages/core/src/plugin-manager.ts"],"sourcesContent":["export const log = {\n info: (...args: unknown[]) => console.log(new Date().toISOString(), '[INFO]', ...args),\n warn: (...args: unknown[]) => console.warn(new Date().toISOString(), '[WARN]', ...args),\n error: (...args: unknown[]) => console.error(new Date().toISOString(), '[ERROR]', ...args),\n debug: (...args: unknown[]) => {\n if (process.env.OPENACP_DEBUG) console.log(new Date().toISOString(), '[DEBUG]', ...args)\n },\n}\n","import { z } from 'zod'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { log } from './log.js'\n\nconst BaseChannelSchema = z.object({\n enabled: z.boolean().default(false),\n adapter: z.string().optional(), // package name for plugin adapters\n}).passthrough()\n\nexport const PLUGINS_DIR = path.join(os.homedir(), '.openacp', 'plugins')\n\nconst AgentSchema = z.object({\n command: z.string(),\n args: z.array(z.string()).default([]),\n workingDirectory: z.string().optional(),\n env: z.record(z.string(), z.string()).default({}),\n})\n\nexport const ConfigSchema = z.object({\n channels: z.record(z.string(), BaseChannelSchema),\n agents: z.record(z.string(), AgentSchema),\n defaultAgent: z.string(),\n workspace: z.object({\n baseDir: z.string().default('~/openacp-workspace'),\n }).default({}),\n security: z.object({\n allowedUserIds: z.array(z.string()).default([]),\n maxConcurrentSessions: z.number().default(5),\n sessionTimeoutMinutes: z.number().default(60),\n }).default({}),\n})\n\nexport type Config = z.infer<typeof ConfigSchema>\n\nexport function expandHome(p: string): string {\n if (p.startsWith('~')) {\n return path.join(os.homedir(), p.slice(1))\n }\n return p\n}\n\nconst DEFAULT_CONFIG = {\n channels: {\n telegram: {\n enabled: false,\n botToken: \"YOUR_BOT_TOKEN_HERE\",\n chatId: 0,\n notificationTopicId: null,\n assistantTopicId: null\n }\n },\n agents: {\n claude: { command: \"claude-agent-acp\", args: [], env: {} },\n codex: { command: \"codex\", args: [\"--acp\"], env: {} }\n },\n defaultAgent: \"claude\",\n workspace: { baseDir: \"~/openacp-workspace\" },\n security: { allowedUserIds: [], maxConcurrentSessions: 5, sessionTimeoutMinutes: 60 }\n}\n\nexport class ConfigManager {\n private config!: Config\n private configPath: string\n\n constructor() {\n this.configPath = process.env.OPENACP_CONFIG_PATH || expandHome('~/.openacp/config.json')\n }\n\n async load(): Promise<void> {\n // 1. Ensure directory exists\n const dir = path.dirname(this.configPath)\n fs.mkdirSync(dir, { recursive: true })\n\n // 2. If config file doesn't exist, create default\n if (!fs.existsSync(this.configPath)) {\n fs.writeFileSync(this.configPath, JSON.stringify(DEFAULT_CONFIG, null, 2))\n log.info(`Config created at ${this.configPath}`)\n log.info('Please edit it with your Telegram bot token and chat ID, then restart.')\n process.exit(1)\n }\n\n // 3. Read and parse\n const raw = JSON.parse(fs.readFileSync(this.configPath, 'utf-8'))\n\n // 4. Apply env var overrides\n this.applyEnvOverrides(raw)\n\n // 5. Validate with Zod\n const result = ConfigSchema.safeParse(raw)\n if (!result.success) {\n log.error('Config validation failed:')\n for (const issue of result.error.issues) {\n log.error(` ${issue.path.join('.')}: ${issue.message}`)\n }\n process.exit(1)\n }\n this.config = result.data\n }\n\n get(): Config {\n return this.config\n }\n\n async save(updates: Record<string, unknown>): Promise<void> {\n // Read current file, merge updates, write back\n const raw = JSON.parse(fs.readFileSync(this.configPath, 'utf-8'))\n this.deepMerge(raw, updates)\n fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2))\n // Re-validate and update in-memory config\n const result = ConfigSchema.safeParse(raw)\n if (result.success) {\n this.config = result.data\n }\n }\n\n resolveWorkspace(input?: string): string {\n if (!input) {\n const resolved = expandHome(this.config.workspace.baseDir)\n fs.mkdirSync(resolved, { recursive: true })\n return resolved\n }\n if (input.startsWith('/') || input.startsWith('~')) {\n const resolved = expandHome(input)\n fs.mkdirSync(resolved, { recursive: true })\n return resolved\n }\n // Named workspace → lowercase, under baseDir\n const name = input.toLowerCase()\n const resolved = path.join(expandHome(this.config.workspace.baseDir), name)\n fs.mkdirSync(resolved, { recursive: true })\n return resolved\n }\n\n async exists(): Promise<boolean> {\n return fs.existsSync(this.configPath)\n }\n\n getConfigPath(): string {\n return this.configPath\n }\n\n async writeNew(config: Config): Promise<void> {\n const dir = path.dirname(this.configPath)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2))\n }\n\n private applyEnvOverrides(raw: Record<string, unknown>): void {\n const overrides: [string, string[]][] = [\n ['OPENACP_TELEGRAM_BOT_TOKEN', ['channels', 'telegram', 'botToken']],\n ['OPENACP_TELEGRAM_CHAT_ID', ['channels', 'telegram', 'chatId']],\n ['OPENACP_DEFAULT_AGENT', ['defaultAgent']],\n ]\n for (const [envVar, configPath] of overrides) {\n const value = process.env[envVar]\n if (value !== undefined) {\n let target = raw as Record<string, any>\n for (let i = 0; i < configPath.length - 1; i++) {\n if (!target[configPath[i]]) target[configPath[i]] = {}\n target = target[configPath[i]]\n }\n const key = configPath[configPath.length - 1]\n // Convert chatId to number\n target[key] = key === 'chatId' ? Number(value) : value\n }\n }\n }\n\n private deepMerge(target: Record<string, any>, source: Record<string, any>): void {\n for (const key of Object.keys(source)) {\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\n if (!target[key]) target[key] = {}\n this.deepMerge(target[key], source[key])\n } else {\n target[key] = source[key]\n }\n }\n }\n}\n","import { execSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { createRequire } from 'node:module'\nimport { PLUGINS_DIR } from './config.js'\nimport { log } from './log.js'\nimport type { ChannelAdapter } from './channel.js'\n\nexport interface AdapterFactory {\n name: string\n createAdapter(core: any, config: any): ChannelAdapter\n}\n\nfunction ensurePluginsDir(): void {\n fs.mkdirSync(PLUGINS_DIR, { recursive: true })\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) {\n fs.writeFileSync(pkgPath, JSON.stringify({ name: 'openacp-plugins', private: true, dependencies: {} }, null, 2))\n }\n}\n\nexport function installPlugin(packageName: string): void {\n ensurePluginsDir()\n log.info(`Installing ${packageName}...`)\n execSync(`npm install ${packageName} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n log.info(`${packageName} installed successfully.`)\n}\n\nexport function uninstallPlugin(packageName: string): void {\n ensurePluginsDir()\n log.info(`Uninstalling ${packageName}...`)\n execSync(`npm uninstall ${packageName} --prefix \"${PLUGINS_DIR}\"`, { stdio: 'inherit' })\n log.info(`${packageName} uninstalled.`)\n}\n\nexport function listPlugins(): Record<string, string> {\n const pkgPath = path.join(PLUGINS_DIR, 'package.json')\n if (!fs.existsSync(pkgPath)) return {}\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n return pkg.dependencies || {}\n}\n\nexport async function loadAdapterFactory(packageName: string): Promise<AdapterFactory | null> {\n try {\n const require = createRequire(path.join(PLUGINS_DIR, 'package.json'))\n const resolved = require.resolve(packageName)\n const mod = await import(resolved)\n\n // Plugin must export `adapterFactory` or default export conforming to AdapterFactory\n const factory: AdapterFactory | undefined = mod.adapterFactory || mod.default\n if (!factory || typeof factory.createAdapter !== 'function') {\n log.error(`Plugin ${packageName} does not export a valid AdapterFactory (needs .createAdapter())`)\n return null\n }\n return factory\n } catch (err) {\n log.error(`Failed to load plugin ${packageName}:`, err)\n log.error(`Run: npx openacp install ${packageName}`)\n return null\n }\n}\n"],"mappings":"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","names":["resolved","fs","path","require"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../packages/core/src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { ConfigManager } from './config.js'\nimport { OpenACPCore } from './core.js'\nimport { loadAdapterFactory } from './plugin-manager.js'\nimport { log } from './log.js'\n\nlet shuttingDown = false\n\nexport async function startServer() {\n // 1. Check config exists, run setup if not\n const configManager = new ConfigManager()\n const configExists = await configManager.exists()\n\n if (!configExists) {\n const { runSetup } = await import('./setup.js')\n const shouldStart = await runSetup(configManager)\n if (!shouldStart) process.exit(0)\n }\n\n // 2. Load config (validates with Zod)\n await configManager.load()\n const config = configManager.get()\n log.info('Config loaded from', configManager.getConfigPath())\n\n // 3. Create core\n const core = new OpenACPCore(configManager)\n\n // 4. Register adapters from config\n for (const [channelName, channelConfig] of Object.entries(config.channels)) {\n if (!channelConfig.enabled) continue\n\n if (channelName === 'telegram') {\n // Built-in adapter — try bundled import first, fall back to relative path for dev\n let TelegramAdapter: any\n try {\n // @ts-ignore — optional peer dependency, may not be installed\n const mod = await import('@openacp/adapter-telegram')\n TelegramAdapter = mod.TelegramAdapter\n } catch {\n // Dev mode: resolve from workspace via relative path\n const adapterPath = new URL('../../adapters/telegram/dist/index.js', import.meta.url).pathname\n const mod = await import(adapterPath)\n TelegramAdapter = mod.TelegramAdapter\n }\n core.registerAdapter('telegram', new TelegramAdapter(core, channelConfig))\n log.info('Telegram adapter registered (built-in)')\n } else if (channelConfig.adapter) {\n // Plugin adapter\n const factory = await loadAdapterFactory(channelConfig.adapter)\n if (factory) {\n const adapter = factory.createAdapter(core, channelConfig)\n core.registerAdapter(channelName, adapter)\n log.info(`${channelName} adapter registered (plugin: ${channelConfig.adapter})`)\n } else {\n log.error(`Skipping channel \"${channelName}\" — adapter \"${channelConfig.adapter}\" failed to load`)\n }\n } else {\n log.error(`Channel \"${channelName}\" has no built-in adapter. Set \"adapter\" field to a plugin package.`)\n }\n }\n\n if (core.adapters.size === 0) {\n log.error('No channels enabled. Enable at least one channel in config.')\n process.exit(1)\n }\n\n // 5. Start\n await core.start()\n\n // 6. Log ready\n const agents = Object.keys(config.agents).join(', ')\n log.info(`OpenACP started. Agents: ${agents}`)\n log.info('Press Ctrl+C to stop.')\n\n // 7. Graceful shutdown\n const shutdown = async (signal: string) => {\n if (shuttingDown) return\n shuttingDown = true\n log.info(`${signal} received. Shutting down...`)\n\n try {\n await core.stop()\n } catch (err) {\n log.error('Error during shutdown:', err)\n }\n\n process.exit(0)\n }\n\n process.on('SIGINT', () => shutdown('SIGINT'))\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n\n process.on('uncaughtException', (err) => {\n log.error('Uncaught exception:', err)\n })\n\n process.on('unhandledRejection', (err) => {\n log.error('Unhandled rejection:', err)\n })\n}\n\n// Direct execution for dev (node packages/core/dist/main.js)\nconst isDirectExecution = process.argv[1]?.endsWith('main.js')\nif (isDirectExecution) {\n startServer().catch((err) => {\n log.error('Fatal:', err)\n process.exit(1)\n })\n}\n"],"mappings":";;;;;;;;;;;;AAOA,IAAI,eAAe;AAEnB,eAAsB,cAAc;AAElC,QAAM,gBAAgB,IAAI,cAAc;AACxC,QAAM,eAAe,MAAM,cAAc,OAAO;AAEhD,MAAI,CAAC,cAAc;AACjB,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,sBAAY;AAC9C,UAAM,cAAc,MAAM,SAAS,aAAa;AAChD,QAAI,CAAC,YAAa,SAAQ,KAAK,CAAC;AAAA,EAClC;AAGA,QAAM,cAAc,KAAK;AACzB,QAAM,SAAS,cAAc,IAAI;AACjC,MAAI,KAAK,sBAAsB,cAAc,cAAc,CAAC;AAG5D,QAAM,OAAO,IAAI,YAAY,aAAa;AAG1C,aAAW,CAAC,aAAa,aAAa,KAAK,OAAO,QAAQ,OAAO,QAAQ,GAAG;AAC1E,QAAI,CAAC,cAAc,QAAS;AAE5B,QAAI,gBAAgB,YAAY;AAE9B,UAAI;AACJ,UAAI;AAEF,cAAM,MAAM,MAAM,OAAO,2BAA2B;AACpD,0BAAkB,IAAI;AAAA,MACxB,QAAQ;AAEN,cAAM,cAAc,IAAI,IAAI,yCAAyC,YAAY,GAAG,EAAE;AACtF,cAAM,MAAM,MAAM,OAAO;AACzB,0BAAkB,IAAI;AAAA,MACxB;AACA,WAAK,gBAAgB,YAAY,IAAI,gBAAgB,MAAM,aAAa,CAAC;AACzE,UAAI,KAAK,wCAAwC;AAAA,IACnD,WAAW,cAAc,SAAS;AAEhC,YAAM,UAAU,MAAM,mBAAmB,cAAc,OAAO;AAC9D,UAAI,SAAS;AACX,cAAM,UAAU,QAAQ,cAAc,MAAM,aAAa;AACzD,aAAK,gBAAgB,aAAa,OAAO;AACzC,YAAI,KAAK,GAAG,WAAW,gCAAgC,cAAc,OAAO,GAAG;AAAA,MACjF,OAAO;AACL,YAAI,MAAM,qBAAqB,WAAW,qBAAgB,cAAc,OAAO,kBAAkB;AAAA,MACnG;AAAA,IACF,OAAO;AACL,UAAI,MAAM,YAAY,WAAW,qEAAqE;AAAA,IACxG;AAAA,EACF;AAEA,MAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,QAAI,MAAM,6DAA6D;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,KAAK,MAAM;AAGjB,QAAM,SAAS,OAAO,KAAK,OAAO,MAAM,EAAE,KAAK,IAAI;AACnD,MAAI,KAAK,4BAA4B,MAAM,EAAE;AAC7C,MAAI,KAAK,uBAAuB;AAGhC,QAAM,WAAW,OAAO,WAAmB;AACzC,QAAI,aAAc;AAClB,mBAAe;AACf,QAAI,KAAK,GAAG,MAAM,6BAA6B;AAE/C,QAAI;AACF,YAAM,KAAK,KAAK;AAAA,IAClB,SAAS,KAAK;AACZ,UAAI,MAAM,0BAA0B,GAAG;AAAA,IACzC;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,GAAG,UAAU,MAAM,SAAS,QAAQ,CAAC;AAC7C,UAAQ,GAAG,WAAW,MAAM,SAAS,SAAS,CAAC;AAE/C,UAAQ,GAAG,qBAAqB,CAAC,QAAQ;AACvC,QAAI,MAAM,uBAAuB,GAAG;AAAA,EACtC,CAAC;AAED,UAAQ,GAAG,sBAAsB,CAAC,QAAQ;AACxC,QAAI,MAAM,wBAAwB,GAAG;AAAA,EACvC,CAAC;AACH;AAGA,IAAM,oBAAoB,QAAQ,KAAK,CAAC,GAAG,SAAS,SAAS;AAC7D,IAAI,mBAAmB;AACrB,cAAY,EAAE,MAAM,CAAC,QAAQ;AAC3B,QAAI,MAAM,UAAU,GAAG;AACvB,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":[]}