#!/usr/bin/env bash
# Real demos for P031 "Why AI Agent Skills Beat Giant Prompts".
# A made-up online coffee roaster (Kettle & Bean) with a 12-procedure support handbook (lab/handbook):
#   giant/   the whole handbook in CLAUDE.md: one giant prompt, read on every model request
#   skills/  three always-on rules in CLAUDE.md; each procedure is a skill (.claude/skills/<name>/SKILL.md)
# The words of each procedure are the same in both (lab/build makes both from the handbook).
# lab/agent runs Claude Code headless (claude -p, Sonnet) with nothing else loaded and prints every skill it loads,
# every command it runs, its reply, and the tokens each model request read. It runs on this Mac's Claude Code login:
# ANTHROPIC_API_KEY is removed from its environment, so no API key is ever used.
# The lab is copied to ~/skills-lab (outside this repo, so Claude Code can't read our own CLAUDE.md/AGENTS.md) and
# removed afterwards. Commands are typed into one real interactive bash; commands + output go to demo_output.json.
# Model answers differ every run: build_script.py reads whatever this run produced.
set -euo pipefail
cd "$(dirname "$0")"
LAB="$HOME/skills-lab"
rm -rf "$LAB"; mkdir -p "$LAB"
cp -R lab/. "$LAB/"
trap 'rm -rf "$LAB"' EXIT

python3 - "$LAB" <<'PY'
import fcntl, json, os, pty, re, select, struct, sys, termios, time, subprocess
LAB = sys.argv[1]
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)
            env = {k: v for k, v in os.environ.items() if k not in ("ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN")}
            os.execvpe("bash", ["bash", "--norc", "--noprofile", "-i"], dict(env, TERM="dumb"))
        self.fd, self.where = fd, ""
        os.write(fd, b"stty -echo; PS1='__REA''DY__:\\W:__ '\n")
        self.read()

    def read(self, timeout=900):
        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()
s.run("build", "./build")
s.run("ls", "ls")
s.run("handbook", "ls handbook")
s.run("giant_words", "wc -w giant/CLAUDE.md")
s.run("giant_heads", "grep '^## ' giant/CLAUDE.md")
s.run("skills_ls", "ls skills/.claude/skills")
s.run("skills_claude", "cat skills/CLAUDE.md")
s.run("skill_head", "head -4 skills/.claude/skills/damaged-parcel/SKILL.md")
OK = '"Reply with just: ok"'
s.run("ok_none", f"./agent --none {OK}")
s.run("ok_giant", f"./agent --giant {OK}")
s.run("ok_skills", f"./agent --skills {OK}")
s.run("torn_mail", "cat mail/torn-bag.txt")
s.run("torn_giant", "./agent --giant mail/torn-bag.txt")
s.run("torn_skills", "./agent --skills mail/torn-bag.txt")
s.run("refund_files", "find skills/.claude/skills/refunds -type f")
s.run("refund_mail", "cat mail/refund.txt")
s.run("refund_skills", "./agent --skills mail/refund.txt")
s.run("refund_giant", "./agent --giant mail/refund.txt")
s.run("inbox_mail", "cat mail/inbox.txt")
s.run("inbox_giant", "./agent --giant mail/inbox.txt --no-reply")
s.run("inbox_skills", "./agent --skills mail/inbox.txt --no-reply")
s.run("grow", "./grow")
claude_version = subprocess.run(["claude", "--version"], capture_output=True, text=True).stdout.strip()
model = json.loads(open(os.path.join(LAB, ".log", "last-skills.jsonl")).readline()).get("model", "")
steps["_meta"] = {"cmd": "", "out": json.dumps({"claude_code": claude_version, "model": model,
                   "run_at": time.strftime("%Y-%m-%d %H:%M %Z")})}
json.dump(steps, open("demo_output.json", "w"), indent=1, ensure_ascii=False)
print("saved demo_output.json")
PY
