From 3cafadba5a39da0a95ab4c9f916f07e01e5cf1c2 Mon Sep 17 00:00:00 2001 From: john Date: Thu, 16 Jul 2026 22:26:47 +0800 Subject: [PATCH] fix(runtime): bundle MindSearch MCP for production --- docs/release-deploy.md | 1 + scripts/build-portal-runtime.mjs | 22 ++++++++++++++++++++++ scripts/release-portal-runtime-prod.sh | 7 ++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/release-deploy.md b/docs/release-deploy.md index b4e1c9a..0318e0f 100644 --- a/docs/release-deploy.md +++ b/docs/release-deploy.md @@ -8,6 +8,7 @@ 1. 构建只发生在本机 Mac:`node scripts/build-portal-runtime.mjs`。 2. 103 只接收 `.runtime/portal/` 打出来的 artifact,不直接覆盖源码树。 + - 所有由 goosed 以 stdio 启动的 Portal MCP 入口都必须打进 artifact,并同时加入发布脚本的必需文件和容器可见性检查;当前包括 `mindspace-sandbox-mcp.mjs` 与 `tkmind-search-mcp.mjs`。 3. 103 在切换前必须做 `Memind` 全量备份,并单独备份持久目录。 4. 103 **禁止** `npm install`、`npm run build`、在线改源码后继续运行。 5. 切换后必须通过 Portal 健康检查;失败立即回滚。 diff --git a/scripts/build-portal-runtime.mjs b/scripts/build-portal-runtime.mjs index a1b7879..fbf51c2 100755 --- a/scripts/build-portal-runtime.mjs +++ b/scripts/build-portal-runtime.mjs @@ -143,6 +143,26 @@ async function bundleSandboxMcp() { await run(esbuildBin, args); } +async function bundleMindSearchMcp() { + if (!(await exists(esbuildBin))) { + throw new Error(`未找到 esbuild: ${esbuildBin}`); + } + console.log('==> 打包 MindSearch MCP 为单文件 runtime'); + const args = [ + 'tkmind-search-mcp.mjs', + '--bundle', + '--platform=node', + '--format=esm', + `--target=${runtimeNodeTarget}`, + '--outfile=.runtime/portal/tkmind-search-mcp.mjs', + '--banner:js=import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);', + ]; + for (const pkg of externalPackages) { + args.push(`--external:${pkg}`); + } + await run(esbuildBin, args); +} + async function bundleAgentRunWorker() { if (!(await exists(esbuildBin))) { throw new Error(`未找到 esbuild: ${esbuildBin}`); @@ -414,6 +434,7 @@ async function writeMetadata() { '', 'Bundled alongside server.mjs (required for sandbox-fs MCP):', ' mindspace-sandbox-mcp.mjs (esbuild bundle; includes schedule-service deps)', + ' tkmind-search-mcp.mjs (esbuild bundle; required when MindSearch is enabled)', ' wechat-mp.bundle.mjs (esbuild bundle; hot-swappable WeChat MP module)', '', 'Post-deploy validation (scripts/check-mindspace-public-links.mjs):', @@ -486,6 +507,7 @@ async function main() { await bundleServer(); await bundleWechatMp(); await bundleSandboxMcp(); + await bundleMindSearchMcp(); await bundleAgentRunWorker(); if (runtimeInstallMode === 'bundle-node-modules' && !skipNodeModules) { await copyNodeModules(); diff --git a/scripts/release-portal-runtime-prod.sh b/scripts/release-portal-runtime-prod.sh index 55ba606..4dd9eee 100755 --- a/scripts/release-portal-runtime-prod.sh +++ b/scripts/release-portal-runtime-prod.sh @@ -152,7 +152,7 @@ fi verify_runtime_artifact() { local missing=0 - for required in server.mjs wechat-mp.bundle.mjs mindspace-sandbox-mcp.mjs mindspace-public-links.mjs dist package.json scripts/run-memind-portal-prod.sh scripts/check-mindspace-public-links.mjs scripts/load-env.mjs scripts/wechat-mp-menu.mjs scripts/memind-portal-tunnel.sh; do + for required in server.mjs wechat-mp.bundle.mjs mindspace-sandbox-mcp.mjs tkmind-search-mcp.mjs mindspace-public-links.mjs dist package.json scripts/run-memind-portal-prod.sh scripts/check-mindspace-public-links.mjs scripts/load-env.mjs scripts/wechat-mp-menu.mjs scripts/memind-portal-tunnel.sh; do if [[ ! -e "${RUNTIME_ROOT}/${required}" ]]; then echo "runtime 产物缺失: ${RUNTIME_ROOT}/${required}" >&2 missing=1 @@ -232,8 +232,8 @@ if [[ -x "${docker_bin}" ]] && "${docker_bin}" ps --format '{{.Names}}' 2>/dev/n echo "goosed dependency check failed: ${container} is not healthy on host port ${host_port}" >&2 missing=1 fi - if ! "${docker_bin}" exec "${container}" sh -lc 'test -x /usr/local/bin/node && test -f /opt/portal/mindspace-sandbox-mcp.mjs' >/dev/null 2>&1; then - echo "goosed dependency check failed: ${container} missing /usr/local/bin/node or /opt/portal/mindspace-sandbox-mcp.mjs" >&2 + if ! "${docker_bin}" exec "${container}" sh -lc 'test -x /usr/local/bin/node && test -f /opt/portal/mindspace-sandbox-mcp.mjs && test -f /opt/portal/tkmind-search-mcp.mjs' >/dev/null 2>&1; then + echo "goosed dependency check failed: ${container} missing /usr/local/bin/node, /opt/portal/mindspace-sandbox-mcp.mjs, or /opt/portal/tkmind-search-mcp.mjs" >&2 missing=1 fi done @@ -627,6 +627,7 @@ say "检查 live 目录中不再保留源码树" allowed_live_mjs=( "${APP_DIR}/server.mjs" "${APP_DIR}/mindspace-sandbox-mcp.mjs" + "${APP_DIR}/tkmind-search-mcp.mjs" "${APP_DIR}/mindspace-public-links.mjs" ) extra_files=""