test(runner): align hosted server contracts

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-23 21:22:49 +00:00
1 parent 753f8a755e
commit 91a66e65bb
4 files changed
+42 -10

No files matched your search

@@ -51,7 +51,9 @@ describe("buildPaperclipTaskMarkdown", () => {
},
});
expect(acceptedConfirmation).toContain("Create child issues from the approved plan only");
expect(acceptedConfirmation).toContain(
"Use create_task to create exactly one standard implementation child containing the complete approved plan",
);
expect(acceptedConfirmation).not.toContain("Make the plan only.");
});
@@ -68,7 +70,9 @@ describe("buildPaperclipTaskMarkdown", () => {
});
expect(acceptedConfirmation).toContain("Accepted plan directive:");
expect(acceptedConfirmation).toContain("Create child issues from the approved plan only");
expect(acceptedConfirmation).toContain(
"Use create_task to create exactly one standard implementation child containing the complete approved plan",
);
expect(acceptedConfirmation).not.toContain("- Work mode: \"planning\"");
});
@@ -58,14 +58,24 @@ describe("paperclip_runner Claude Agent environment probe", () => {
expect(result.status).toBe("warn");
expect(result.checks.some((check) => check.code === "claude_managed_profile_qualified")).toBe(true);
expect(calls).toHaveLength(3);
expect(calls.map((call) => call.url)).toEqual([
"https://api.anthropic.com/v1/agents/agent_test?beta=true",
"https://api.anthropic.com/v1/environments/env_test?beta=true",
"https://api.anthropic.com/v1/agents/agent_test/versions?beta=true",
"https://api.anthropic.com/v1/skills?limit=1&source=custom",
]);
expect(calls.every((call) => (call.init.method ?? "GET") === "GET")).toBe(true);
for (const call of calls) {
expect(call.init.headers).toMatchObject({
"x-api-key": "anthropic-config-secret",
"anthropic-beta": "managed-agents-2026-04-01",
});
}
expect(calls.slice(0, 3).every((call) =>
(call.init.headers as Record<string, string>)["anthropic-beta"] === "managed-agents-2026-04-01"
)).toBe(true);
expect(calls[3]?.init.headers).toMatchObject({
"anthropic-beta": "skills-2025-10-02",
});
expect(JSON.stringify(result)).not.toContain("anthropic-config-secret");
});
+11 -2
View File
@@ -1,3 +1,4 @@
import { existsSync } from "node:fs";
import { createServer } from "node:http";
import { tmpdir } from "node:os";
import { resolve } from "node:path";
@@ -16,6 +17,14 @@ import {
setupRunnerPrpWebSocketServer,
} from "./runner-prp-ws.js";
const fakeCodexAppServer = resolve(
import.meta.dirname,
"../../../packages/paperclip-runner/runner/target/debug/fake-codex-app-server",
);
const runnerBinariesAvailable =
existsSync(defaultCapabilityRunnerdBinary()) && existsSync(fakeCodexAppServer);
const runnerBinaryIt = runnerBinariesAvailable ? it : it.skip;
describe("runner PRP websocket route", () => {
afterEach(() => runnerPrpWebSocketInternals.resetForTests());
@@ -95,7 +104,7 @@ describe("runner PRP websocket route", () => {
server.close();
});
it("carries an authorized runnerd tool call over the shared Paperclip route", async () => {
runnerBinaryIt("carries an authorized runnerd tool call over the shared Paperclip route", async () => {
const server = createServer();
await new Promise<void>((resolveListen) => server.listen(0, "127.0.0.1", resolveListen));
const address = server.address();
@@ -104,7 +113,7 @@ describe("runner PRP websocket route", () => {
const runId = "00000000-0000-4000-8000-000000000779";
const bundle = createRunnerdCodexTransport({
runnerBinary: defaultCapabilityRunnerdBinary(),
codexCommand: resolve(import.meta.dirname, "../../../packages/paperclip-runner/runner/target/debug/fake-codex-app-server"),
codexCommand: fakeCodexAppServer,
codexArgs: [],
prpIdentity: {
runnerInstanceId: "runner-server-route",
@@ -1,5 +1,6 @@
import { createServer } from "node:http";
import { existsSync } from "node:fs";
import { mkdtemp, rm } from "node:fs/promises";
import { createServer } from "node:http";
import { tmpdir } from "node:os";
import { resolve } from "node:path";
@@ -19,6 +20,14 @@ import {
} from "../../realtime/runner-prp-ws.js";
import { PaperclipRunnerToolAuthority } from "./paperclip-runner-tool-authority.js";
const fakeCodexAppServer = resolve(
import.meta.dirname,
"../../../../packages/paperclip-runner/runner/target/debug/fake-codex-app-server",
);
const runnerBinariesAvailable =
existsSync(defaultCapabilityRunnerdBinary()) && existsSync(fakeCodexAppServer);
const runnerBinaryIt = runnerBinariesAvailable ? it : it.skip;
describe("paperclip-runner real server vertical slice", () => {
let temporary: Awaited<ReturnType<typeof startEmbeddedPostgresTestDatabase>>;
const companyId = "00000000-0000-4000-8000-000000000701";
@@ -36,7 +45,7 @@ describe("paperclip-runner real server vertical slice", () => {
await temporary.cleanup();
});
it("runs Rust runnerd through Paperclip PRP and reads the real bound task", async () => {
runnerBinaryIt("runs Rust runnerd through Paperclip PRP and reads the real bound task", async () => {
const db = createDb(temporary.connectionString);
await db.insert(companies).values({ id: companyId, name: "Real runner slice", issuePrefix: "RRS" });
await db.insert(agents).values({
@@ -78,7 +87,7 @@ describe("paperclip-runner real server vertical slice", () => {
const stateDirectory = await mkdtemp(resolve(tmpdir(), "paperclip-runner-real-resume-"));
const bundle = createRunnerdCodexTransport({
runnerBinary: defaultCapabilityRunnerdBinary(),
codexCommand: resolve(import.meta.dirname, "../../../../packages/paperclip-runner/runner/target/debug/fake-codex-app-server"),
codexCommand: fakeCodexAppServer,
codexArgs: [],
stateDirectory,
lifecyclePolicy: { mode: "per_turn", idleTimeoutMs: null },
@@ -147,7 +156,7 @@ describe("paperclip-runner real server vertical slice", () => {
});
const restored = createRunnerdCodexTransport({
runnerBinary: defaultCapabilityRunnerdBinary(),
codexCommand: resolve(import.meta.dirname, "../../../../packages/paperclip-runner/runner/target/debug/fake-codex-app-server"),
codexCommand: fakeCodexAppServer,
codexArgs: [],
stateDirectory,
lifecyclePolicy: { mode: "per_turn", idleTimeoutMs: null },