import { spawn } from 'node:child_process'; import { chmod, copyFile, mkdir, rm, writeFile, } from 'node:fs/promises'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const runtimeRoot = path.join(root, '.runtime', 'deep-search'); const esbuildBin = path.join(root, 'node_modules', '.bin', 'esbuild'); const runtimeNodeTarget = process.env.DEEP_SEARCH_RUNTIME_NODE_TARGET || 'node24'; function run(command, args) { return new Promise((resolve, reject) => { const child = spawn(command, args, { cwd: root, stdio: 'inherit', env: process.env, }); child.once('error', reject); child.once('exit', (code, signal) => { if (code === 0) return resolve(); reject(new Error(`${command} exited with ${code ?? signal}`)); }); }); } await rm(runtimeRoot, { recursive: true, force: true }); await mkdir(path.join(runtimeRoot, 'scripts'), { recursive: true }); await run(esbuildBin, [ 'deep-search-server.mjs', '--bundle', '--platform=node', '--format=esm', `--target=${runtimeNodeTarget}`, '--outfile=.runtime/deep-search/deep-search-server.mjs', '--banner:js=import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);', ]); for (const script of [ 'run-deep-search-prod.sh', 'install-deep-search-runtime-prod.sh', ]) { const source = path.join(root, 'scripts', script); const target = path.join(runtimeRoot, 'scripts', script); await copyFile(source, target); await chmod(target, 0o755); } await writeFile( path.join(runtimeRoot, 'RUNBOOK.txt'), [ 'TKMind Deep Search standalone runtime', '', 'Production base: /Users/john/Project/deep-search-runtime', 'Persistent env: shared/.env', 'Persistent data: data/research.sqlite', 'Release code: releases//', 'Active release: current -> releases//', 'LaunchAgent: cn.tkmind.memind-deep-search', 'Health: http://127.0.0.1:20100/health', 'SearXNG: http://127.0.0.1:20080/search', '', 'The GitHub token stays in shared/.env and is never passed to goosed MCP processes.', 'Portal and memindadm releases are intentionally separate.', '', ].join('\n'), ); console.log(`Deep Search runtime built at ${runtimeRoot}`);