#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
TASK_FILE=""
VERSION=""
DRY_RUN=false
KM_HOST="${KM_HOST:-km}"
KM_XWCODE_BIN="${KM_XWCODE_BIN:-\$HOME/bin/xwcode}"
while [[ $# -gt 0 ]]; do
case "$1" in
--task) TASK_FILE="$2"; shift 2 ;;
--version) VERSION="$2"; shift 2 ;;
--dry-run) DRY_RUN=true; shift ;;
*) echo "usage: $0 --task <task-file.md> [--version vX.Y.Z] [--dry-run]"; exit 1 ;;
esac
done
if [ -z "$TASK_FILE" ]; then
echo "ERROR: --task 为必填参数。自举任务必须是真实开发任务,不设默认值。" >&2
echo " 可用的 task spec 示例: scripts/dogfood/task-diffclassifier-model.md" >&2
exit 1
fi
if [ ! -f "$TASK_FILE" ]; then
echo "ERROR: task file 不存在: $TASK_FILE" >&2
exit 1
fi
if ! grep -q 'allow_git_operations:[[:space:]]*true' "$TASK_FILE"; then
echo "WARN: task spec 未设置 allow_git_operations: true —— xwcode 将无法 commit/push。" >&2
fi
if [ -z "$VERSION" ]; then
VERSION=$(awk '/^\[workspace\.package\]/{inw=1;next} /^\[/{inw=0} inw && /^version *= *"/{v=$0;sub(/^version *= *"/,"",v);sub(/".*/,"",v);print v;exit}' "$PROJECT_ROOT/Cargo.toml" 2>/dev/null || echo "unknown")
fi
TASK_NAME="$(basename "$TASK_FILE")"
WSLDEV_RELEASE="$PROJECT_ROOT/target/release/xwcode"
echo "=== xwcode 自举编排 ==="
echo "Version: $VERSION"
echo "Task: $TASK_NAME"
echo "KM: $KM_HOST"
echo "Dry-run: $DRY_RUN"
echo ""
echo "[pre] 检查 km comm 身份..."
MACHINE_ID=$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$KM_HOST" "bash -l -c 'XW_COMM_AGENT=xwcode ~/comm-mcp/bin/comm status 2>/dev/null | grep machine || echo UNKNOWN'" 2>/dev/null || echo "SSH_FAIL")
if echo "$MACHINE_ID" | grep -q "wsl-dev"; then
echo " ⚠️ WARN: km comm 报告 machine=wsl-dev(应为 km)——出站 comm 会错误路由。"
echo " 修复: ssh $KM_HOST 'echo \"export XW_COMM_MACHINE=km\" >> ~/.bashrc'"
elif echo "$MACHINE_ID" | grep -q "km"; then
echo " ✅ machine=km"
else
echo " ℹ️ machine=$MACHINE_ID"
fi
if $DRY_RUN; then
echo ""
echo "=== DRY RUN — 仅验证环境,不实际执行 ==="
echo " SSH: $(ssh -o BatchMode=yes -o ConnectTimeout=10 "$KM_HOST" 'echo OK' 2>/dev/null || echo 'FAIL')"
echo " comm: $(XW_COMM_AGENT=claude-ar ~/comm-mcp/bin/comm status 2>/dev/null | head -1 || echo 'UNKNOWN')"
echo " binary: $WSLDEV_RELEASE $([ -f "$WSLDEV_RELEASE" ] && echo 'exists' || echo 'missing (需先构建)')"
echo "=== DRY RUN 结束 ==="
exit 0
fi
echo "[1/4] 构建 release 二进制..."
cd "$PROJECT_ROOT"
cargo build --release --bin xwcode 2>&1 | tail -5
echo " binary: $WSLDEV_RELEASE ($(du -h "$WSLDEV_RELEASE" | cut -f1))"
echo "[2/4] 部署到 $KM_HOST..."
ssh -o BatchMode=yes "$KM_HOST" "mkdir -p ~/bin" 2>/dev/null || true
if scp -o BatchMode=yes "$WSLDEV_RELEASE" "$KM_HOST:~/bin/xwcode" 2>/dev/null; then
echo " scp 部署成功"
else
echo " scp 失败,使用 SSH 管道部署..."
ssh "$KM_HOST" "cat > ~/bin/xwcode" < "$WSLDEV_RELEASE"
ssh "$KM_HOST" "chmod +x ~/bin/xwcode"
echo " SSH 部署成功"
fi
ssh -o BatchMode=yes "$KM_HOST" "bash -l -c '~/bin/xwcode --version 2>&1 | head -1'" || echo " WARN: 版本验证失败"
echo "[3/4] 复制 task spec 到 km..."
ssh "$KM_HOST" "mkdir -p ~/dogfood-tasks" 2>/dev/null || true
scp -o BatchMode=yes "$TASK_FILE" "$KM_HOST:~/dogfood-tasks/$TASK_NAME" 2>/dev/null || \
ssh "$KM_HOST" "cat > ~/dogfood-tasks/$TASK_NAME" < "$TASK_FILE"
echo "[4/4] 通过 comm 发送任务通知..."
XW_COMM_AGENT=claude-ar ~/comm-mcp/bin/comm send xwcode \
"SELF_BOOTSTRAP TASK v${VERSION}: ${TASK_NAME}
Task spec: ~/dogfood-tasks/${TASK_NAME}
Branch: xwcode/v${VERSION}/$(basename "$TASK_NAME" .md)
Base: origin/master
Action:
1. cd ~/xwcode && git fetch origin && git checkout master && git pull
2. git checkout -b xwcode/v${VERSION}/$(basename "$TASK_NAME" .md) origin/master
3. ~/bin/xwcode --no-tui --task ~/dogfood-tasks/${TASK_NAME} --diagnose
4. 完成后: git add+commit+push origin xwcode/v${VERSION}/$(basename "$TASK_NAME" .md)
5. comm send claude-ar: 'complete: <commit-hash>'"
echo ""
echo "=== 编排完成 ==="
echo ""
echo "验证方法:"
echo " 1. 检查 km comm 收件箱: ssh $KM_HOST XW_COMM_AGENT=xwcode ~/comm-mcp/bin/comm check"
echo " 2. 等待 xwcode 回复或检查分支: git fetch && git branch -r | grep xwcode/v${VERSION}"
echo " 3. 查看报告: ./scripts/dogfood/run_dogfood_km.sh report --version v${VERSION}"
echo " 4. 收集结果: ./scripts/dogfood/run_dogfood_km.sh collect --version v${VERSION}"