#!/usr/bin/env bash
# Real demos for P011 "Agent Skills vs MCP: When Each One Wins".
# A made-up coffee shop (Kettle & Bean) with:
#   - an MCP server (lab/orders-server, official MCP Python SDK 2.3.0, protocol 2026-07-28) holding 5 orders, in Docker
#   - a skill (lab/shop/.claude/skills/late-order-reply/SKILL.md): how support replies to a late order
#   - lab/agent: runs Claude Code headless (claude -p, Sonnet) with nothing else loaded, and prints each tool it uses
# GitHub's official MCP server (ghcr.io/github/github-mcp-server) is started only to list and measure its tools,
# with a fake token: it never reaches GitHub.
# The lab is copied to ~/kettle-and-bean (outside this repo, so the agent can't read our project files) and
# removed afterwards. Commands are typed into one real interactive bash; commands + output go to demo_output.json.
# Model answers differ every run: the script reads whatever this run produced.
set -euo pipefail
cd "$(dirname "$0")"
LAB="$HOME/kettle-and-bean"
rm -rf "$LAB"; mkdir -p "$LAB"
cp -R lab/. "$LAB/"
trap 'rm -rf "$LAB"' EXIT
docker build -q -t orders-mcp "$LAB/orders-server" >/dev/null
docker pull -q ghcr.io/github/github-mcp-server >/dev/null
GH_VERSION=$( (sleep 1) | docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN=demo ghcr.io/github/github-mcp-server stdio 2>&1 | grep -o 'version=v[0-9.]*' | head -1 || true)

python3 - "$LAB" "$GH_VERSION" <<'PY'
import fcntl, json, os, pty, re, select, struct, sys, termios, time, subprocess
LAB, GH_VERSION = sys.argv[1], sys.argv[2]
READY = re.compile(rb"__READY__:(.*?):__ ")
steps = {}

def clean(text):
    text = re.sub(r"\x1b\[[0-9;?]*[A-Za-z]|\x1b[()][A-Z0-9]", "", text)
    lines = [l.rstrip("\r").split("\r")[-1] for l in text.split("\n")]
    return "\n".join(l.rstrip() for l in lines).strip("\n")

class Shell:
    def __init__(self):
        pid, fd = pty.fork()
        if pid == 0:
            fcntl.ioctl(0, termios.TIOCSWINSZ, struct.pack("HHHH", 40, 80, 0, 0))
            os.chdir(LAB)
            os.execvpe("bash", ["bash", "--norc", "--noprofile", "-i"], dict(os.environ, TERM="dumb"))
        self.fd, self.where = fd, ""
        os.write(fd, b"stty -echo; PS1='__REA''DY__:\\W:__ '\n")
        self.read()

    def read(self, timeout=600):
        buf, end = b"", time.time() + timeout
        while time.time() < end:
            if select.select([self.fd], [], [], 0.3)[0]:
                buf += os.read(self.fd, 65536)
                m = None
                for m in READY.finditer(buf):
                    pass
                if m:
                    self.where = m.group(1).decode()
                    return clean(buf[:m.start()].decode("utf-8", "replace"))
        raise SystemExit(f"timed out; last output: {buf[-400:]!r}")

    def run(self, key, cmd):
        shown = f"{self.where}$ {cmd}"
        os.write(self.fd, cmd.encode() + b"\n")
        t = time.time()
        out = self.read()
        steps[key] = {"cmd": shown, "out": out}
        print(f"--- {key} ({time.time()-t:.0f}s)\n{shown}\n{out}\n", flush=True)
        return out

s = Shell()
Q1 = "Which of our orders are late right now?"
s.run("ls", "ls")
s.run("ask_plain", f'./agent "{Q1}"')
s.run("server_tools", "grep -A2 '@mcp.tool' orders-server/server.py")
s.run("list_req", "cat requests/list.json | jq .")
s.run("list", "(cat requests/list.json; sleep 1) | docker run -i --rm orders-mcp | jq '.result.tools[] | {name, description}'")
s.run("call", "(cat requests/call.json; sleep 1) | docker run -i --rm orders-mcp | jq -c '.result.structuredContent.result[] | {id, customer, days_late}'")
s.run("ask_mcp", f'./agent --mcp "{Q1}"')
s.run("reply_mcp", './agent --mcp "Write a reply to the customer of order 1042."')
s.run("skill_tree", "find shop -type f")
s.run("skill_cat", "cat shop/.claude/skills/late-order-reply/SKILL.md")
s.run("reply_skill", './agent --mcp --skill "Write a reply to the customer of order 1042."')
s.run("reply_skill_1043", './agent --mcp --skill "Write a reply to the customer of order 1043."')
s.run("gh_count", "(cat requests/list.json; sleep 2) | docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN=demo ghcr.io/github/github-mcp-server stdio 2>/dev/null | jq '.result.tools | length'")
s.run("gh_chars", "(cat requests/list.json; sleep 2) | docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN=demo ghcr.io/github/github-mcp-server stdio 2>/dev/null | jq -c '[.result.tools[] | {name, description, inputSchema}]' | wc -c")
OK = '"Reply with just: ok"'
s.run("cost_none", f"./agent {OK}")
s.run("cost_skill", f"./agent --skill {OK}")
s.run("cost_mcp", f"./agent --mcp {OK}")
s.run("cost_github", f"./agent --github {OK}")
s.run("cost_github_all", f"LOAD_ALL_TOOLS=1 ./agent --github {OK}")

claude_version = subprocess.run(["claude", "--version"], capture_output=True, text=True).stdout.strip()
steps["_meta"] = {"cmd": "", "out": json.dumps({"claude_code": claude_version, "github_mcp_server": GH_VERSION,
                   "mcp_python_sdk": "2.3.0", "model": "sonnet", "run_at": time.strftime("%Y-%m-%d %H:%M %Z")})}
json.dump(steps, open("demo_output.json", "w"), indent=1)
print("saved demo_output.json")
PY
