diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25bf525..1c1edb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,4 +25,4 @@ jobs: run: bunx biome check . - name: Test - run: bun run --filter './packages/*' test + run: bun run test:ci diff --git a/package.json b/package.json index 046fc28..59dece5 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "typecheck": "bunx tsc --build", "format": "biome format --write .", "test": "bun run --filter './packages/*' test", + "test:ci": "bun run --filter './packages/*' test:ci", "changeset": "bunx changeset", "version": "bunx changeset version", "release": "bun run build && bun test && node scripts/publish-all.mjs" diff --git a/packages/cli-workflow/package.json b/packages/cli-workflow/package.json index f6ae640..e484658 100644 --- a/packages/cli-workflow/package.json +++ b/packages/cli-workflow/package.json @@ -22,7 +22,8 @@ "yaml": "^2.8.4" }, "scripts": { - "test": "vitest run" + "test": "vitest run", + "test:ci": "vitest run" }, "publishConfig": { "access": "public" diff --git a/packages/workflow-agent-builtin/package.json b/packages/workflow-agent-builtin/package.json index c6dd1e8..91568c1 100644 --- a/packages/workflow-agent-builtin/package.json +++ b/packages/workflow-agent-builtin/package.json @@ -18,7 +18,8 @@ } }, "scripts": { - "test": "bun test" + "test": "bun test", + "test:ci": "bun test" }, "dependencies": { "@uncaged/json-cas": "^0.5.2", diff --git a/packages/workflow-agent-claude-code/package.json b/packages/workflow-agent-claude-code/package.json index 2bed2b0..604c0d4 100644 --- a/packages/workflow-agent-claude-code/package.json +++ b/packages/workflow-agent-claude-code/package.json @@ -18,7 +18,8 @@ } }, "scripts": { - "test": "bun test" + "test": "bun test", + "test:ci": "bun test" }, "dependencies": { "@uncaged/json-cas": "^0.5.2", diff --git a/packages/workflow-agent-hermes/__tests__/acp-client.test.ts b/packages/workflow-agent-hermes/__tests__/acp-client.test.ts index e1d6b91..64b7bcd 100644 --- a/packages/workflow-agent-hermes/__tests__/acp-client.test.ts +++ b/packages/workflow-agent-hermes/__tests__/acp-client.test.ts @@ -2,8 +2,6 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test"; import { HermesAcpClient } from "../src/acp-client.js"; -const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; - describe("handleSessionUpdate — helper extraction", () => { let client: HermesAcpClient; @@ -94,75 +92,4 @@ describe("handleSessionUpdate — helper extraction", () => { }); }); -describe("HermesAcpClient", () => { - let client: HermesAcpClient; - beforeEach(() => { - client = new HermesAcpClient(); - }); - - afterEach(async () => { - await client.close(); - }); - - it( - "connect() returns a UUID sessionId", - async () => { - const sessionId = await client.connect(process.cwd()); - expect(typeof sessionId).toBe("string"); - expect(sessionId).toMatch(UUID_RE); - }, - { timeout: 2 * 60 * 1000 }, - ); - - it( - "prompt() returns a non-empty text response", - async () => { - await client.connect(process.cwd()); - const result = await client.prompt("Reply with exactly the word: PONG"); - expect(typeof result.text).toBe("string"); - expect(result.text.length).toBeGreaterThan(0); - expect(typeof result.sessionId).toBe("string"); - expect(result.sessionId).toMatch(UUID_RE); - }, - { timeout: 2 * 60 * 1000 }, - ); - - it( - "prompt() can be called twice on the same session (resume)", - async () => { - await client.connect(process.cwd()); - - const first = await client.prompt("Say the word ALPHA and nothing else."); - expect(first.text.length).toBeGreaterThan(0); - - const second = await client.prompt("Now say the word BETA and nothing else."); - expect(second.text.length).toBeGreaterThan(0); - - expect(first.sessionId).toBe(second.sessionId); - }, - { timeout: 2 * 60 * 1000 }, - ); - - // TODO(#435): flaky — depends on live LLM; mock or move to integration suite - it.skip( - "prompt() collects structured messages including tool calls", - async () => { - await client.connect(process.cwd()); - const result = await client.prompt("Run this command: echo TOOL_DETAIL_TEST"); - expect(result.messages.length).toBeGreaterThan(0); - // Should have at least one tool message (the echo command) - const toolMessages = result.messages.filter((m) => m.role === "tool"); - expect(toolMessages.length).toBeGreaterThan(0); - // Tool message should contain the output - const toolContent = toolMessages[0]?.content ?? ""; - expect(toolContent).toContain("TOOL_DETAIL_TEST"); - // Should have assistant messages with tool_calls - const assistantWithTools = result.messages.filter( - (m) => m.role === "assistant" && m.tool_calls !== null, - ); - expect(assistantWithTools.length).toBeGreaterThan(0); - }, - { timeout: 2 * 60 * 1000 }, - ); -}); diff --git a/packages/workflow-agent-hermes/__tests__/integration/acp-client.integration.test.ts b/packages/workflow-agent-hermes/__tests__/integration/acp-client.integration.test.ts new file mode 100644 index 0000000..4c05c0a --- /dev/null +++ b/packages/workflow-agent-hermes/__tests__/integration/acp-client.integration.test.ts @@ -0,0 +1,75 @@ +import { afterEach, beforeEach, describe, expect, it } from "bun:test"; + +import { HermesAcpClient } from "../../src/acp-client.js"; + +const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + +describe("HermesAcpClient", () => { + let client: HermesAcpClient; + + beforeEach(() => { + client = new HermesAcpClient(); + }); + + afterEach(async () => { + await client.close(); + }); + + it( + "connect() returns a UUID sessionId", + async () => { + const sessionId = await client.connect(process.cwd()); + expect(typeof sessionId).toBe("string"); + expect(sessionId).toMatch(UUID_RE); + }, + { timeout: 2 * 60 * 1000 }, + ); + + it( + "prompt() returns a non-empty text response", + async () => { + await client.connect(process.cwd()); + const result = await client.prompt("Reply with exactly the word: PONG"); + expect(typeof result.text).toBe("string"); + expect(result.text.length).toBeGreaterThan(0); + expect(typeof result.sessionId).toBe("string"); + expect(result.sessionId).toMatch(UUID_RE); + }, + { timeout: 2 * 60 * 1000 }, + ); + + it( + "prompt() can be called twice on the same session (resume)", + async () => { + await client.connect(process.cwd()); + + const first = await client.prompt("Say the word ALPHA and nothing else."); + expect(first.text.length).toBeGreaterThan(0); + + const second = await client.prompt("Now say the word BETA and nothing else."); + expect(second.text.length).toBeGreaterThan(0); + + expect(first.sessionId).toBe(second.sessionId); + }, + { timeout: 2 * 60 * 1000 }, + ); + + // TODO(#435): flaky — depends on live LLM; mock or move to integration suite + it.skip( + "prompt() collects structured messages including tool calls", + async () => { + await client.connect(process.cwd()); + const result = await client.prompt("Run this command: echo TOOL_DETAIL_TEST"); + expect(result.messages.length).toBeGreaterThan(0); + const toolMessages = result.messages.filter((m) => m.role === "tool"); + expect(toolMessages.length).toBeGreaterThan(0); + const toolContent = toolMessages[0]?.content ?? ""; + expect(toolContent).toContain("TOOL_DETAIL_TEST"); + const assistantWithTools = result.messages.filter( + (m) => m.role === "assistant" && m.tool_calls !== null, + ); + expect(assistantWithTools.length).toBeGreaterThan(0); + }, + { timeout: 2 * 60 * 1000 }, + ); +}); diff --git a/packages/workflow-agent-hermes/__tests__/resume-e2e.test.ts b/packages/workflow-agent-hermes/__tests__/integration/resume-e2e.integration.test.ts similarity index 100% rename from packages/workflow-agent-hermes/__tests__/resume-e2e.test.ts rename to packages/workflow-agent-hermes/__tests__/integration/resume-e2e.integration.test.ts diff --git a/packages/workflow-agent-hermes/package.json b/packages/workflow-agent-hermes/package.json index 12de6fb..d9e9082 100644 --- a/packages/workflow-agent-hermes/package.json +++ b/packages/workflow-agent-hermes/package.json @@ -18,7 +18,8 @@ } }, "scripts": { - "test": "bun test" + "test": "bun test", +"test:ci": "bun test __tests__/*.test.ts" }, "dependencies": { "@uncaged/json-cas": "^0.5.2", diff --git a/packages/workflow-agent-kit/package.json b/packages/workflow-agent-kit/package.json index 8d893a6..1716494 100644 --- a/packages/workflow-agent-kit/package.json +++ b/packages/workflow-agent-kit/package.json @@ -15,7 +15,8 @@ } }, "scripts": { - "test": "bun test" + "test": "bun test", + "test:ci": "bun test" }, "dependencies": { "@uncaged/json-cas": "^0.5.2", diff --git a/packages/workflow-moderator/package.json b/packages/workflow-moderator/package.json index 71f785a..98c81ea 100644 --- a/packages/workflow-moderator/package.json +++ b/packages/workflow-moderator/package.json @@ -15,7 +15,8 @@ } }, "scripts": { - "test": "bun test" + "test": "bun test", + "test:ci": "bun test" }, "dependencies": { "@uncaged/workflow-protocol": "workspace:^",