CI / contract (push) Has been cancelled
症状:装好插件后调 list_projects 返回 auth_required,模型被技能里"先让用户完成 MCP 授权(codex mcp login deta_mcp)"带偏,用户卡在登录环节。 根因两条:① 启动器只透传环境变量 DETA_TOKEN,而 Finder/Dock 启动的桌面应用不继承终端环境,登录助手写的 ~/.deta 凭据根本进不去宿主进程;② 技能/README 仍留着远程形态的 OAuth 指引,本机形态里那条命令不存在。 修复:启动器按 DETA_TOKEN 环境变量 → ~/.deta/env → ~/.deta/credentials.json 顺序解析令牌并在 stderr 报告来源(不打印值);技能改为"让用户跑登录助手 → 开新会话",并明确区分 MCP 侧云令牌与面板侧 deta.city 登录;两份 README 的登录流程改为"登录一次、开新会话即可"(无需 source / launchctl / 改 .zshrc / 重启应用)。studio 0.3.1 → 0.3.2。 实测(隔离 HOME):四种取令牌路径与优先级、缺令牌时的引导文案均符合预期。
98 lines
4.4 KiB
Bash
Executable File
98 lines
4.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# DETA 产品插件的本机 MCP stdio 启动器(唯一入口,多产品共用)
|
||
#
|
||
# 两个宿主(Codex 插件 / dsh 组合包)都通过本脚本拉起同一个领域服务;
|
||
# 产品差异只由 --profile 决定(工作区默认位置、工具面),宿主侧只声明"调哪个脚本、带哪个档位"。
|
||
#
|
||
# 用法:deta-mcp.sh [--profile <studio|writer>]
|
||
#
|
||
# 依赖:node + 已构建的领域服务运行时
|
||
#
|
||
# 环境变量:
|
||
# DETA_SERVER_ROOT 领域服务运行时根目录(未设时自动查找,见下)
|
||
# DETA_WORKSPACE AML 工作目录(引擎侧工作区真值;缺省 ~/.deta/<profile>/workspace)
|
||
# ANT_HEADLESS_WORKSPACE 同上(兼容旧名,DETA_WORKSPACE 优先)
|
||
# DETA_TOKEN deta.city 门户令牌(可选;不注入则云类工具返回 auth_required)
|
||
# ANT_WORKSPACE_BRIDGE_URL 网关基址(可选;与项目 ID 一起启用 Studio 执行器中继)
|
||
# DETA_SURFACE 工具面覆盖(缺省 full)
|
||
set -euo pipefail
|
||
|
||
# ── 产品档位:宿主在声明里传 --profile;缺省 studio ──
|
||
PROFILE="${DETA_PROFILE:-studio}"
|
||
while [ $# -gt 0 ]; do
|
||
case "$1" in
|
||
--profile) PROFILE="${2:?--profile 需要一个值}"; shift 2 ;;
|
||
*) break ;;
|
||
esac
|
||
done
|
||
|
||
# ── 运行时解析:显式 DETA_SERVER_ROOT → 本机引擎包安装位置 → 本机开发检出(打印提示)──
|
||
ROOT="${DETA_SERVER_ROOT:-}"
|
||
if [ -z "$ROOT" ]; then
|
||
for cand in "$HOME/.deta/runtime" "$HOME/Dev/ant/ant-copilot"; do
|
||
if [ -f "$cand/dist/deta-mcp.mjs" ] || [ -f "$cand/dist/src/headless/mcp-server.js" ]; then ROOT="$cand"; break; fi
|
||
done
|
||
fi
|
||
|
||
if ! command -v node >/dev/null 2>&1; then
|
||
echo "[deta] 未找到 node,请先安装 Node.js" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# 入口优先取 esbuild 打包形态:tsc 产物在 Node ESM 下会因依赖包的目录 import 直接失败
|
||
ENTRY=""
|
||
if [ -n "$ROOT" ]; then
|
||
if [ -f "$ROOT/dist/deta-mcp.mjs" ]; then
|
||
ENTRY="$ROOT/dist/deta-mcp.mjs"
|
||
elif [ -f "$ROOT/dist/src/headless/mcp-server.js" ]; then
|
||
ENTRY="$ROOT/dist/src/headless/mcp-server.js"
|
||
echo "[deta] 警告:回落到未打包产物,请先在该运行时目录执行 npm run build:mcp" >&2
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$ENTRY" ]; then
|
||
echo "[deta] 未找到领域服务运行时(已尝试:DETA_SERVER_ROOT、\$HOME/.deta/runtime、\$HOME/Dev/ant/ant-copilot)" >&2
|
||
echo "[deta] 请安装本机引擎包,或设置 DETA_SERVER_ROOT 指向已构建的领域服务仓库" >&2
|
||
exit 1
|
||
fi
|
||
|
||
if [ "$ROOT" = "$HOME/Dev/ant/ant-copilot" ]; then
|
||
echo "[deta] 提示:使用本机开发检出 ${ROOT}(非打包运行时)" >&2
|
||
fi
|
||
|
||
# ── 工作目录:宿主不会传项目目录(cwd 通常是插件根),按产品档位定稳定位置 ──
|
||
WS="${DETA_WORKSPACE:-${ANT_HEADLESS_WORKSPACE:-$HOME/.deta/$PROFILE/workspace}}"
|
||
mkdir -p "$WS"
|
||
export ANT_HEADLESS_WORKSPACE="$WS"
|
||
|
||
# ── 工具面:产品档位缺省全量面;DETA_SURFACE 可覆盖(如 engine)──
|
||
export DETA_TOOL_SURFACE="${DETA_SURFACE:-full}"
|
||
|
||
# ── 云令牌:显式环境变量 → ~/.deta/env → ~/.deta/credentials.json ──
|
||
# 桌面应用(Finder/Dock 启动)不会继承终端的 export,也不是每个人都有 launchctl 注入,
|
||
# 因此登录助手写下的凭据必须由启动器自己解析——这是"登录一次即可用"的关键路径。
|
||
TOKEN_SOURCE=""
|
||
if [ -n "${DETA_TOKEN:-}" ]; then
|
||
TOKEN_SOURCE="环境变量"
|
||
fi
|
||
if [ -z "${DETA_TOKEN:-}" ] && [ -f "$HOME/.deta/env" ]; then
|
||
# shellcheck disable=SC1090
|
||
. "$HOME/.deta/env" >/dev/null 2>&1 || true
|
||
if [ -n "${DETA_TOKEN:-}" ]; then TOKEN_SOURCE="$HOME/.deta/env"; fi
|
||
fi
|
||
if [ -z "${DETA_TOKEN:-}" ] && [ -f "$HOME/.deta/credentials.json" ]; then
|
||
DETA_TOKEN="$(node -e "try{const c=JSON.parse(require('node:fs').readFileSync(process.env.HOME+'/.deta/credentials.json','utf8'));if(c&&typeof c.token==='string')process.stdout.write(c.token)}catch(e){}" 2>/dev/null || true)"
|
||
export DETA_TOKEN
|
||
if [ -n "${DETA_TOKEN:-}" ]; then TOKEN_SOURCE="$HOME/.deta/credentials.json"; fi
|
||
fi
|
||
|
||
if [ -n "${DETA_TOKEN:-}" ]; then
|
||
CLOUD_STATE="已注入(来源=${TOKEN_SOURCE})"
|
||
else
|
||
CLOUD_STATE="未注入——云类工具将返回 auth_required:运行 bin/deta-login.mjs 登录后开新会话"
|
||
fi
|
||
|
||
echo "[deta] 档位=${PROFILE} 运行时=${ROOT} 工作区=${WS} 工具面=${DETA_TOOL_SURFACE} 云令牌=${CLOUD_STATE}" >&2
|
||
|
||
exec node "$ENTRY" "$@"
|