feat: Add ACP (Agent Client Protocol) support (#2947)

Co-authored-by: opencode-bot <devnull@opencode.local>
Co-authored-by: Dax Raad <d@ironbay.co>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Joe Schmitt
2025-10-20 17:55:22 -04:00
committed by GitHub
parent 835fa9fb81
commit f3f21194ae
13 changed files with 991 additions and 160 deletions

View File

@@ -0,0 +1,109 @@
import { describe, expect, test } from "bun:test"
import { spawn } from "child_process"
describe("ACP Server", () => {
test("initialize and shutdown", async () => {
const proc = spawn("bun", ["run", "--conditions=development", "src/index.ts", "acp"], {
cwd: process.cwd(),
stdio: ["pipe", "pipe", "pipe"],
env: { ...process.env, OPENCODE: "1" },
})
const encoder = new TextEncoder()
const decoder = new TextDecoder()
let initResponse: any = null
proc.stdout.on("data", (chunk: Buffer) => {
const lines = decoder.decode(chunk).split("\n")
for (const line of lines) {
const trimmed = line.trim()
if (!trimmed) continue
try {
const msg = JSON.parse(trimmed)
if (msg.id === 1) initResponse = msg
} catch (e) {}
}
})
proc.stdin.write(
encoder.encode(
JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "initialize",
params: { protocolVersion: 1 },
}) + "\n",
),
)
await new Promise((resolve) => setTimeout(resolve, 500))
expect(initResponse).toBeTruthy()
expect(initResponse.result.protocolVersion).toBe(1)
expect(initResponse.result.agentCapabilities).toBeTruthy()
proc.kill()
}, 10000)
test("create session", async () => {
const proc = spawn("bun", ["run", "--conditions=development", "src/index.ts", "acp"], {
cwd: process.cwd(),
stdio: ["pipe", "pipe", "pipe"],
env: { ...process.env, OPENCODE: "1" },
})
const encoder = new TextEncoder()
const decoder = new TextDecoder()
let sessionResponse: any = null
proc.stdout.on("data", (chunk: Buffer) => {
const lines = decoder.decode(chunk).split("\n")
for (const line of lines) {
const trimmed = line.trim()
if (!trimmed) continue
try {
const msg = JSON.parse(trimmed)
if (msg.id === 2) sessionResponse = msg
} catch (e) {}
}
})
proc.stdin.write(
encoder.encode(
JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "initialize",
params: { protocolVersion: 1 },
}) + "\n",
),
)
await new Promise((resolve) => setTimeout(resolve, 500))
proc.stdin.write(
encoder.encode(
JSON.stringify({
jsonrpc: "2.0",
id: 2,
method: "session/new",
params: {
cwd: process.cwd(),
mcpServers: [],
},
}) + "\n",
),
)
await new Promise((resolve) => setTimeout(resolve, 1000))
expect(sessionResponse).toBeTruthy()
expect(sessionResponse.result.sessionId).toBeTruthy()
proc.kill()
}, 10000)
})