// Node-only ways in, with a context of their own (createNodeContext in a temp state dir) and no call: // the code may call nothing. // transport: for atlibs' Node CLI (ATLIBS_TRANSPORTS=/js/cli.mjs): a module that lists // com.fedfork.exec.mcp.message in its calls reaches code mode as a host call. // node js/cli.mjs: a composition handler for the Rust atlibs CLI (--handler 'mcp=exec: ' // --allow-exec): the handler envelope { handler, caller, nsid, reason, input } on stdin, the response on stdout. import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { pathToFileURL } from "node:url"; import { createNodeContext } from "@publicdomainrelay/atlibs/server/index.js"; import { MESSAGE, codeMode } from "./index.js"; const server = (stateDir) => codeMode({ ctx: createNodeContext({ id: "code-mode", stateDir }) }); export const transport = { [MESSAGE]: ({ stateDir }) => server(join(stateDir, "code-mode")).calls[MESSAGE] }; if (import.meta.url === pathToFileURL(process.argv[1]).href) { let body = ""; for await (const chunk of process.stdin) body += chunk; const { input } = JSON.parse(body); const stateDir = mkdtempSync(join(tmpdir(), "code-mode-")); try { process.stdout.write(`${JSON.stringify(await server(stateDir).message(input))}\n`); } finally { rmSync(stateDir, { recursive: true, force: true }); } process.exit(0); }