chore(deps): upgrade claude-code-acp to v0.8.5 and improve test lifecycle management

This commit is contained in:
Mohamed Boudra
2025-10-26 09:51:18 +01:00
parent 7d1ef63c8f
commit fdaf403f13
4 changed files with 112 additions and 61 deletions
+12
View File
@@ -214,5 +214,17 @@
"createdAt": "2025-10-26T07:59:07.111Z", "createdAt": "2025-10-26T07:59:07.111Z",
"lastActivityAt": "2025-10-26T07:59:17.913Z", "lastActivityAt": "2025-10-26T07:59:17.913Z",
"cwd": "/Users/moboudra/dev/voice-dev" "cwd": "/Users/moboudra/dev/voice-dev"
},
{
"id": "69af3b81-92d0-48a6-abd6-e357a4cf67b5",
"title": "Manage Test Agent Lifecycle",
"sessionId": "9f844826-2c8e-414f-a236-a9279233b053",
"options": {
"type": "claude",
"sessionId": "9f844826-2c8e-414f-a236-a9279233b053"
},
"createdAt": "2025-10-26T08:32:55.726Z",
"lastActivityAt": "2025-10-26T08:37:47.226Z",
"cwd": "/Users/moboudra/dev/voice-dev"
} }
] ]
+1 -1
View File
@@ -19,7 +19,7 @@
"dependencies": { "dependencies": {
"@agentclientprotocol/sdk": "^0.4.9", "@agentclientprotocol/sdk": "^0.4.9",
"@ai-sdk/openai": "^2.0.52", "@ai-sdk/openai": "^2.0.52",
"@boudra/claude-code-acp": "^0.8.4", "@boudra/claude-code-acp": "^0.8.5",
"@deepgram/sdk": "^3.4.0", "@deepgram/sdk": "^3.4.0",
"@modelcontextprotocol/sdk": "^1.20.1", "@modelcontextprotocol/sdk": "^1.20.1",
"@openrouter/ai-sdk-provider": "^1.2.0", "@openrouter/ai-sdk-provider": "^1.2.0",
@@ -1,4 +1,4 @@
import { describe, it, expect, beforeAll, afterAll } from "vitest"; import { describe, it, expect, beforeAll, afterEach, afterAll } from "vitest";
import { AgentManager } from "./agent-manager.js"; import { AgentManager } from "./agent-manager.js";
import type { AgentUpdate, AgentNotification } from "./types.js"; import type { AgentUpdate, AgentNotification } from "./types.js";
import type { RequestPermissionRequest } from "@agentclientprotocol/sdk"; import type { RequestPermissionRequest } from "@agentclientprotocol/sdk";
@@ -7,19 +7,31 @@ import { tmpdir } from "os";
import { join } from "path"; import { join } from "path";
describe("AgentManager", () => { describe("AgentManager", () => {
let manager: AgentManager;
let tmpDir: string; let tmpDir: string;
const createdAgents: Array<{ manager: AgentManager; agentId: string }> = [];
beforeAll(async () => { beforeAll(async () => {
manager = new AgentManager();
tmpDir = await mkdtemp(join(tmpdir(), "acp-test-")); tmpDir = await mkdtemp(join(tmpdir(), "acp-test-"));
}); });
afterEach(async () => {
// Clean up all agents created during tests
for (const { manager, agentId } of createdAgents) {
try {
await manager.deleteAgent(agentId);
} catch (error) {
console.error(`Failed to delete agent ${agentId}:`, error);
}
}
createdAgents.length = 0;
});
afterAll(async () => { afterAll(async () => {
await rm(tmpDir, { recursive: true, force: true }); await rm(tmpDir, { recursive: true, force: true });
}); });
it("should create file after accepting plan", async () => { it("should create file after accepting plan", async () => {
const manager = new AgentManager();
let permissionRequest: RequestPermissionRequest | null = null; let permissionRequest: RequestPermissionRequest | null = null;
let requestId: string | null = null; let requestId: string | null = null;
const testFile = join(tmpDir, "test.txt"); const testFile = join(tmpDir, "test.txt");
@@ -28,6 +40,7 @@ describe("AgentManager", () => {
cwd: tmpDir, cwd: tmpDir,
initialMode: "plan", initialMode: "plan",
}); });
createdAgents.push({ manager, agentId });
const unsubscribe = manager.subscribeToUpdates( const unsubscribe = manager.subscribeToUpdates(
agentId, agentId,
@@ -79,14 +92,16 @@ describe("AgentManager", () => {
expect(agentInfo?.currentModeId).toBe("acceptEdits"); expect(agentInfo?.currentModeId).toBe("acceptEdits");
} finally { } finally {
unsubscribe(); unsubscribe();
await manager.killAgent(agentId);
} }
}, 120000); }, 120000);
describe("persistence", () => {
it.only("should load persisted agent and send new prompt", async () => { it.only("should load persisted agent and send new prompt", async () => {
const manager = new AgentManager();
const agentId = await manager.createAgent({ const agentId = await manager.createAgent({
cwd: tmpDir, cwd: tmpDir,
}); });
createdAgents.push({ manager, agentId });
await manager.sendPrompt(agentId, "echo 'first message'"); await manager.sendPrompt(agentId, "echo 'first message'");
@@ -111,6 +126,12 @@ describe("AgentManager", () => {
const newManager = new AgentManager(); const newManager = new AgentManager();
await newManager.initialize(); await newManager.initialize();
// Update the tracking to use the new manager instance
const trackingIndex = createdAgents.findIndex((a) => a.agentId === agentId);
if (trackingIndex >= 0) {
createdAgents[trackingIndex] = { manager: newManager, agentId };
}
const agents = newManager.listAgents(); const agents = newManager.listAgents();
const loadedAgent = agents.find((a) => a.id === agentId); const loadedAgent = agents.find((a) => a.id === agentId);
const loadedClaudeSessionId = newManager.getClaudeSessionId(agentId); const loadedClaudeSessionId = newManager.getClaudeSessionId(agentId);
@@ -147,7 +168,6 @@ describe("AgentManager", () => {
expect(finalUpdates.length).toBeGreaterThan(0); expect(finalUpdates.length).toBeGreaterThan(0);
console.log("Final updates:", finalUpdates); console.log("Final updates:", finalUpdates);
await newManager.killAgent(agentId);
}, 120000); }, 120000);
}); });
});
@@ -556,6 +556,25 @@ export class AgentManager {
}, 100); }, 100);
} }
/**
* Delete an agent completely
* Kills the process and removes it from persistence
*/
async deleteAgent(agentId: string): Promise<void> {
const agent = this.agents.get(agentId);
if (!agent) {
throw new Error(`Agent ${agentId} not found`);
}
// Kill the agent process
await this.killAgent(agentId);
// Remove from persistence
await this.persistence.remove(agentId);
console.log(`[Agent ${agentId}] Deleted from persistence`);
}
/** /**
* Get the status of an agent * Get the status of an agent
*/ */