77 *
88 * Flow:
99 * 1. Spin up a tiny local OpenAPI server (one operation, returns 42).
10- * 2. Write a temp executor.jsonc that points at it as a source.
11- * 3. Spawn the compiled `executor-sidecar` binary with EXECUTOR_PORT=0
10+ * 2. Spawn the compiled `executor-sidecar` binary with EXECUTOR_PORT=0
1211 * and parse the `EXECUTOR_READY:<port>` sentinel.
13- * 4. Connect via MCP streamable HTTP, call the `execute` tool with code
14- * that invokes the OpenAPI tool, assert the answer round-trips as 42.
12+ * 3. Connect via MCP streamable HTTP, call the `execute` tool with code
13+ * that registers and invokes the OpenAPI tool, assert the answer
14+ * round-trips as 42.
1515 *
1616 * Run after `bun ./scripts/build-sidecar.ts`. Exits non-zero on any
1717 * deviation so it can gate CI.
1818 */
19- import { mkdtemp , rm , writeFile } from "node:fs/promises" ;
19+ import { mkdtemp , rm } from "node:fs/promises" ;
2020import { tmpdir } from "node:os" ;
2121import { join , resolve } from "node:path" ;
2222import { spawn , type Subprocess } from "bun" ;
@@ -127,8 +127,10 @@ const startOpenApiServer = () => {
127127} ;
128128
129129const waitForReadyPort = ( proc : Subprocess < "ignore" , "pipe" , "pipe" > ) : Promise < number > =>
130+ // oxlint-disable-next-line executor/no-promise-reject -- boundary: standalone build-time smoke harness, no Effect runtime
130131 new Promise ( ( resolveReady , rejectReady ) => {
131132 const deadline = setTimeout ( ( ) => {
133+ // oxlint-disable-next-line executor/no-promise-reject, executor/no-error-constructor -- boundary: standalone smoke harness reporting a build-time timeout
132134 rejectReady ( new Error ( `sidecar did not announce ready within ${ READY_TIMEOUT_MS } ms` ) ) ;
133135 } , READY_TIMEOUT_MS ) ;
134136
@@ -150,6 +152,7 @@ const waitForReadyPort = (proc: Subprocess<"ignore", "pipe", "pipe">): Promise<n
150152 const { value, done } = await reader . read ( ) ;
151153 if ( done ) {
152154 clearTimeout ( deadline ) ;
155+ // oxlint-disable-next-line executor/no-promise-reject, executor/no-error-constructor -- boundary: standalone smoke harness, stdout-closed surfaced as rejection
153156 rejectReady ( new Error ( "sidecar stdout closed before ready" ) ) ;
154157 return ;
155158 }
@@ -179,18 +182,6 @@ const main = async () => {
179182 console . log ( `[smoke-sidecar] scope: ${ scopeDir } ` ) ;
180183 console . log ( `[smoke-sidecar] openapi: ${ openapi . origin } ` ) ;
181184
182- const config = {
183- sources : [
184- {
185- kind : "openapi" ,
186- spec : `${ openapi . origin } /openapi.json` ,
187- baseUrl : openapi . origin ,
188- namespace : "petstore" ,
189- } ,
190- ] ,
191- } ;
192- await writeFile ( join ( scopeDir , "executor.jsonc" ) , JSON . stringify ( config , null , 2 ) ) ;
193-
194185 const proc = spawn ( {
195186 cmd : [ BINARY ] ,
196187 env : {
@@ -217,9 +208,11 @@ const main = async () => {
217208 if ( exitCode === null ) proc . kill ( "SIGKILL" ) ;
218209 }
219210 openapi . server . stop ( true ) ;
211+ // oxlint-disable-next-line executor/no-promise-catch -- boundary: best-effort tempdir cleanup in a standalone smoke harness
220212 await rm ( scopeDir , { recursive : true , force : true } ) . catch ( ( ) => { } ) ;
221213 } ;
222214
215+ // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: standalone smoke harness needs a finally to tear down the spawned binary + http server
223216 try {
224217 const port = await waitForReadyPort ( proc ) ;
225218 const mcpUrl = new URL ( `http://127.0.0.1:${ port } /mcp` ) ;
@@ -236,9 +229,16 @@ const main = async () => {
236229 if ( ! hasExecute ) fail ( `MCP tools/list missing "execute": ${ JSON . stringify ( tools . tools ) } ` ) ;
237230
238231 // Drive the running OpenAPI server through a multi-step orchestration
239- // in one execute. Covers: array list response, path param dispatch, and
240- // object responses — all going out over real HTTP from inside QuickJS.
232+ // in one execute. Covers: source registration, array list response, path
233+ // param dispatch, and object responses — all going out over real HTTP from
234+ // inside QuickJS.
241235 const code = `
236+ await tools.executor.openapi.addSource({
237+ scope: ${ JSON . stringify ( scopeDir ) } ,
238+ spec: ${ JSON . stringify ( `${ openapi . origin } /openapi.json` ) } ,
239+ baseUrl: ${ JSON . stringify ( openapi . origin ) } ,
240+ namespace: "petstore",
241+ });
242242const list = await tools.petstore.pets.listPets({});
243243const fetched = await tools.petstore.pets.getPet({ petId: list[1].id });
244244return {
0 commit comments