CI / contract (push) Has been cancelled
WorkBuddy 自定义 MCP 支持 command/args/env(取证:其二进制 calculateConfigHash 先判 entry.command),因此走与 Codex 同款的本机 stdio full 工具面,不退远程引擎面。 落地:① 启动器多维护一个 MCP 稳定入口 ~/.deta/bin/deta-mcp-<档位>(指向当前插件副本,升级自动刷新;WB 信任哈希按命令行算,路径稳定=升级不重弹信任);② deta-cli 新增 install-workbuddy [--http]——备份并合并 ~/.workbuddy/mcp.json(同名旧条目与旧远程条目替换掉,防双工具面)、把插件内全部技能装进 ~/.workbuddy/skills/(单一事实源,带 icon.svg)、用宿主将执行的同一条命令做真实握手自证;③ aml-design 技能两处 Codex 特有措辞改宿主中立;④ 契约校验加 E7(装配源齐备 + README 指引);⑤ 探针 scripts/verify-workbuddy.sh(配置形态/稳定入口/技能/握手/WB 日志,5 项断言)。 实测:studio 0.3.16 已装副本重跑幂等通过(握手 39 工具);writer 0.1.7 在沙箱 HOME 验证(deta_writer + report-authoring 技能 + 握手 39 工具)。WB 侧需重启并点一次信任确认。
88 lines
3.4 KiB
Bash
88 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
||
# 探针:WorkBuddy 接入(deta install-workbuddy 的验收)
|
||
#
|
||
# 断言:
|
||
# ① ~/.workbuddy/mcp.json 合法且含 deta_<档位> 的 stdio 条目(command 指向稳定入口,无残留远程条目)
|
||
# ② 稳定入口 ~/.deta/bin/deta-mcp-<档位> 存在且可执行
|
||
# ③ 技能 ~/.workbuddy/skills/aml-design/ 已安装(SKILL.md + icon.svg)
|
||
# ④ 用宿主将要执行的同一条命令做真实 MCP 握手(报工具数)
|
||
# ⑤ WorkBuddy 日志里该 server 已握手(非致命:应用未重启时跳过)
|
||
#
|
||
# 用法:bash scripts/verify-workbuddy.sh [档位,缺省 studio]
|
||
set -u
|
||
PROFILE="${1:-studio}"
|
||
WB="$HOME/.workbuddy"
|
||
NAME="deta_${PROFILE}"
|
||
SHIM="$HOME/.deta/bin/deta-mcp-${PROFILE}"
|
||
pass=0
|
||
fail=0
|
||
ok() { printf ' PASS %s\n' "$1"; pass=$((pass + 1)); }
|
||
no() { printf ' FAIL %s\n' "$1"; fail=$((fail + 1)); }
|
||
warn() { printf ' WARN %s\n' "$1"; }
|
||
|
||
echo "== WorkBuddy 接入检查(档位=${PROFILE},服务名=${NAME})"
|
||
|
||
# ① 配置
|
||
if [ -f "$WB/mcp.json" ]; then
|
||
RESULT="$(python3 - "$WB/mcp.json" "$NAME" "$SHIM" <<'PY'
|
||
import json, sys
|
||
try:
|
||
d = json.load(open(sys.argv[1]))
|
||
except Exception as e:
|
||
print(f'ERR 配置不是合法 JSON: {e}'); sys.exit(0)
|
||
servers = (d.get('mcpServers') or {})
|
||
name, shim = sys.argv[2], sys.argv[3]
|
||
e = servers.get(name)
|
||
if not e:
|
||
print(f'ERR 缺少 {name} 条目'); sys.exit(0)
|
||
if e.get('type') != 'stdio':
|
||
print(f"ERR 形态不对: {e.get('type')}"); sys.exit(0)
|
||
if e.get('command') != shim:
|
||
print(f"ERR command 应为稳定入口: {e.get('command')}"); sys.exit(0)
|
||
legacy = [k for k in servers if k == 'deta_mcp']
|
||
if legacy:
|
||
print(f'ERR 仍残留远程条目: {legacy}'); sys.exit(0)
|
||
print('OK')
|
||
PY
|
||
)"
|
||
if [ "$RESULT" = "OK" ]; then ok "mcp.json 条目形态正确(stdio + 稳定入口,无残留)"; else no "$RESULT"; fi
|
||
else
|
||
no "没有 $WB/mcp.json"
|
||
fi
|
||
|
||
# ② 稳定入口
|
||
if [ -x "$SHIM" ]; then ok "稳定入口存在且可执行"; else no "稳定入口缺失或不可执行:$SHIM"; fi
|
||
|
||
# ③ 技能
|
||
if [ -f "$WB/skills/aml-design/SKILL.md" ]; then
|
||
if grep -q "list_capabilities" "$WB/skills/aml-design/SKILL.md"; then ok "技能已安装(SKILL.md 含能力目录指引)"; else no "技能内容不完整(缺 list_capabilities 指引)"; fi
|
||
if [ -f "$WB/skills/aml-design/icon.svg" ]; then ok "技能图标已安装"; else warn "技能图标缺失(icon.svg)"; fi
|
||
else
|
||
no "技能未安装:$WB/skills/aml-design/SKILL.md"
|
||
fi
|
||
|
||
# ④ 真实握手(与宿主将执行的是同一条命令)
|
||
if [ -x "$SHIM" ]; then
|
||
OUT="$(timeout 30 bash "$SHIM" < /dev/null 2>&1 || bash "$SHIM" < /dev/null 2>&1 || true)"
|
||
TOOLS="$(printf '%s' "$OUT" | grep -o '工具面: full([0-9]* 个)' | head -1)"
|
||
if [ -n "$TOOLS" ]; then ok "握手自证(${TOOLS})"; else no "握手失败:$(printf '%s' "$OUT" | head -2)"; fi
|
||
else
|
||
no "无法握手:稳定入口不存在"
|
||
fi
|
||
|
||
# ⑤ WorkBuddy 是否已加载(应用未重启时 WARN 而非 FAIL)
|
||
LDIR="$WB/logs/$(date +%Y-%m-%d)"
|
||
if [ -d "$LDIR" ]; then
|
||
if grep -hq "MCP-Connect.*ok configId=custom-mcp:${NAME}" "$LDIR"/*.log 2>/dev/null; then
|
||
ok "WorkBuddy 已握手(日志见 MCP-Connect ok)"
|
||
else
|
||
warn "今天的 WorkBuddy 日志里还没有 ${NAME} 的握手 —— 重启 WorkBuddy 后再看"
|
||
fi
|
||
else
|
||
warn "没有今天的 WorkBuddy 日志目录(应用今天没启动过?)"
|
||
fi
|
||
|
||
echo
|
||
echo "结果:${pass} 通过 / ${fail} 失败"
|
||
[ "$fail" -eq 0 ]
|