import assert from "node:assert/strict"; import test from "node:test"; import { AppServerClient } from "../src/app-server-client.js"; import { runReadOnlySmoke } from "../src/smoke.js"; import { FakeAppServer, rawThread, successfulHandshake } from "./fake-app-server.js"; test("opt-in smoke workflow synchronizes, classifies, inspects, and stays read-only", async () => { const fake = new FakeAppServer(successfulHandshake((request, server) => { if (request.method === "thread/list") { server.respond(request, { data: [rawThread("current", { status: { type: "idle" } })], nextCursor: null, backwardsCursor: null }); } else if (request.method === "thread/loaded/list") { server.respond(request, { data: ["current"], nextCursor: null }); } else if (request.method === "thread/read") { server.respond(request, { thread: rawThread("current", { status: { type: "idle" } }) }); } })); const result = await runReadOnlySmoke(new AppServerClient({ url: "ws://127.0.0.1:4500", webSocketFactory: fake.factory, }), "ws://127.0.0.1:4500"); assert.equal(result.inspectedThreadId, "current"); assert.equal(result.inspectedStatus, "idle"); assert.deepEqual(result.emittedMethods, ["thread/list", "thread/loaded/list", "thread/read"]); const permitted = new Set(["initialize", "initialized", ...result.emittedMethods]); assert.deepEqual(fake.frames.map((frame) => frame.method as string).filter((method) => !permitted.has(method)), []); });