From 6588f58eb30fc690d16109515962f09c1b909e75 Mon Sep 17 00:00:00 2001 From: Mani Sarkar Date: Wed, 2 Sep 2026 19:49:58 +0100 Subject: [PATCH 1/5] feat(demo-sparkles): add hackathon demo scripts for SliceCheck scenarios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three runnable scenarios covering fail→fix (scenario 1), open PR audit (scenario 2), and retrospective closed-PR audit (scenario 3), plus a preflight checker to validate all dependencies before the live demo. Adds the SliceCheck health endpoint slice spec to PROGRESS.md. Claude-Session: https://claude.ai/code/session_01WUgA32wA2VYbLkioRkSh7w --- demo-sparkles/preflight.sh | 63 +++++++++++++++++++ demo-sparkles/scenario-1-create-pr.sh | 72 +++++++++++++++++++++ demo-sparkles/scenario-1-push-fix.sh | 86 ++++++++++++++++++++++++++ demo-sparkles/scenario-2-open-prs.sh | 20 ++++++ demo-sparkles/scenario-3-closed-prs.sh | 30 +++++++++ docs/plan/PROGRESS.md | 10 +++ 6 files changed, 281 insertions(+) create mode 100644 demo-sparkles/preflight.sh create mode 100644 demo-sparkles/scenario-1-create-pr.sh create mode 100644 demo-sparkles/scenario-1-push-fix.sh create mode 100644 demo-sparkles/scenario-2-open-prs.sh create mode 100644 demo-sparkles/scenario-3-closed-prs.sh diff --git a/demo-sparkles/preflight.sh b/demo-sparkles/preflight.sh new file mode 100644 index 0000000..9fdb376 --- /dev/null +++ b/demo-sparkles/preflight.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# demo/preflight.sh — run at 20:40, before code freeze +# Confirms every dependency for all three scenarios is green + +set -e + +WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" # ← fill in after wrangler deploy +REPO="neomatrix369/tripwire" +GITHUB_TOKEN="${GITHUB_TOKEN:?Set GITHUB_TOKEN env var}" + +echo "━━━ SliceCheck Demo Preflight ━━━" +echo "" + +# 1. Worker is live +echo -n "[1] Worker reachable... " +STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$WORKER_URL/") +[ "$STATUS" = "200" ] && echo "✅ $WORKER_URL" || echo "❌ Got HTTP $STATUS — check wrangler deploy" + +# 2. Audit endpoint returns HTML +echo -n "[2] Audit endpoint (closed PRs)... " +AUDIT=$(curl -s "$WORKER_URL/audit?repo=$REPO&state=closed&limit=3") +echo "$AUDIT" | grep -q "SliceCheck" && echo "✅ Returns HTML" || echo "❌ No SliceCheck in response — check Worker logs" + +# 3. Audit endpoint (open PRs) +echo -n "[3] Audit endpoint (open PRs)... " +AUDIT_OPEN=$(curl -s "$WORKER_URL/audit?repo=$REPO&state=open&limit=5") +echo "$AUDIT_OPEN" | grep -q "SliceCheck" && echo "✅ Returns HTML" || echo "❌ Failed" + +# 4. GitHub token has repo access +echo -n "[4] GitHub token — can read closed PRs... " +PR_COUNT=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://api.github.com/repos/$REPO/pulls?state=closed&per_page=3" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))") +[ "$PR_COUNT" -gt "0" ] && echo "✅ $PR_COUNT closed PRs found" || echo "❌ 0 PRs returned — check token scope (needs repo)" + +# 5. Webhook registered +echo -n "[5] Webhook registered on repo... " +HOOKS=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://api.github.com/repos/$REPO/hooks" | python3 -c \ + "import sys,json; hooks=json.load(sys.stdin); print(next((h['config']['url'] for h in hooks if 'slicecheck' in h['config'].get('url','')), 'NOT FOUND'))") +echo "$HOOKS" | grep -q "slicecheck" && echo "✅ $HOOKS" || echo "⚠️ Not found — webhook scenario won't work. Register in GitHub → Repo → Settings → Webhooks" + +# 6. gh CLI authenticated +echo -n "[6] gh CLI authenticated... " +gh auth status &>/dev/null && echo "✅" || echo "❌ Run: gh auth login" + +# 7. Demo branch doesn't already exist (clean state) +echo -n "[7] Demo branch clean... " +git fetch --quiet +git branch -r | grep -q "demo/slicecheck-health" && echo "⚠️ Old demo branch exists — run: git push origin --delete demo/slicecheck-health" || echo "✅" + +# 8. PROGRESS.md has the demo slice +echo -n "[8] PROGRESS.md has demo slice... " +grep -q "SliceCheck health endpoint" PROGRESS.md && echo "✅" || echo "❌ Add the demo slice to PROGRESS.md first" + +# 9. Fallback GIF exists +echo -n "[9] Fallback GIF recorded... " +ls demo/fallback-*.gif &>/dev/null && echo "✅" || echo "⚠️ No fallback GIF found — run scenario 1 now and record it with Kap" + +echo "" +echo "━━━ Preflight complete ━━━" +echo "AUDIT URL (closed): $WORKER_URL/audit?repo=$REPO&state=closed&limit=5" +echo "AUDIT URL (open): $WORKER_URL/audit?repo=$REPO&state=open&limit=5" +echo "WORKER HEALTH: $WORKER_URL/" diff --git a/demo-sparkles/scenario-1-create-pr.sh b/demo-sparkles/scenario-1-create-pr.sh new file mode 100644 index 0000000..8cfa266 --- /dev/null +++ b/demo-sparkles/scenario-1-create-pr.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# demo/scenario-1-create-pr.sh +# Creates a PR that DELIBERATELY fails SliceCheck. +# The implementation is real but missing tests and README — +# exactly what the PROGRESS.md slice requires. + +set -e + +WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" +REPO="neomatrix369/tripwire" +BRANCH="demo/slicecheck-health-$(date +%s)" + +echo "Creating demo branch: $BRANCH" +git checkout main && git pull +git checkout -b "$BRANCH" + +# Add the health endpoint to slicecheck/src/entry.py +# This is REAL code — but it's missing tests and README update +cat >> slicecheck/src/entry.py << 'PYEOF' + + +async def handle_health(request, env): + """GET /health — returns service status and secret presence check.""" + import json + + secrets_status = { + "github": "ok" if getattr(env, "GITHUB_TOKEN", None) else "missing", + "anthropic": "ok" if getattr(env, "ANTHROPIC_API_KEY", None) else "missing", + "webhook": "ok" if getattr(env, "GITHUB_WEBHOOK_SECRET", None) else "missing", + } + missing = [k for k, v in secrets_status.items() if v == "missing"] + + body = { + "status": "degraded" if missing else "ok", + "version": "1.0.0", + "secrets": secrets_status, + } + if missing: + body["missing"] = missing + + from workers import Response + return Response( + json.dumps(body), + headers={"content-type": "application/json"} + ) +PYEOF + +# Wire it into the router in entry.py +# (append a route — assumes the router is at the end of on_fetch) +sed -i '' 's|return Response("Not found", status=404)|if request.url.endswith("/health"):\n return await handle_health(request, env)\n return Response("Not found", status=404)|' slicecheck/src/entry.py + +git add slicecheck/src/entry.py +git commit -m "Add SliceCheck health endpoint" + +echo "Pushing branch..." +git push -u origin "$BRANCH" + +echo "Opening PR..." +gh pr create \ + --repo "$REPO" \ + --title "Add SliceCheck health endpoint" \ + --body "Adds GET /health to the SliceCheck Worker. Returns service status and secret presence." \ + --base main \ + --head "$BRANCH" + +echo "" +echo "✅ PR opened. SliceCheck will fire in ~10 seconds." +echo "Watch: https://github.com/$REPO/pulls" +echo "" +echo "Expected verdict: ❌ FAIL — missing tests, missing README update" +echo "" +echo "When the FAIL comment appears, run: bash demo/scenario-1-push-fix.sh $BRANCH" diff --git a/demo-sparkles/scenario-1-push-fix.sh b/demo-sparkles/scenario-1-push-fix.sh new file mode 100644 index 0000000..9a799b3 --- /dev/null +++ b/demo-sparkles/scenario-1-push-fix.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# demo/scenario-1-push-fix.sh +# Pushes the missing tests + README update. +# SliceCheck re-fires and posts ✅ PASS. + +set -e + +BRANCH="${1:?Usage: bash scenario-1-push-fix.sh }" +REPO="neomatrix369/tripwire" + +git checkout "$BRANCH" + +# Add the missing tests +mkdir -p slicecheck/tests +cat > slicecheck/tests/test_health.py << 'PYEOF' +"""Tests for SliceCheck /health endpoint.""" +import pytest +from unittest.mock import MagicMock + +# Import the handler directly +import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) +from entry import handle_health + +class FakeEnv: + GITHUB_TOKEN = "ghp_test" + ANTHROPIC_API_KEY = "sk-ant-test" + GITHUB_WEBHOOK_SECRET = "test-secret" + +class FakeEnvMissing: + GITHUB_TOKEN = None + ANTHROPIC_API_KEY = "sk-ant-test" + GITHUB_WEBHOOK_SECRET = "test-secret" + +@pytest.mark.asyncio +async def test_health_ok(): + import json + fake_request = MagicMock() + fake_request.url = "https://example.com/health" + response = await handle_health(fake_request, FakeEnv()) + body = json.loads(response.body) + assert body["status"] == "ok" + assert body["version"] == "1.0.0" + assert all(v == "ok" for v in body["secrets"].values()) + +@pytest.mark.asyncio +async def test_health_degraded_missing_github(): + import json + fake_request = MagicMock() + fake_request.url = "https://example.com/health" + response = await handle_health(fake_request, FakeEnvMissing()) + body = json.loads(response.body) + assert body["status"] == "degraded" + assert "github" in body["missing"] +PYEOF + +# Add the missing README section +cat >> slicecheck/README.md << 'MDEOF' + +## Health Check + +Verify the Worker is running and all secrets are configured: + +```bash +curl https://slicecheck..workers.dev/health +``` + +Healthy response: +```json +{"status":"ok","version":"1.0.0","secrets":{"github":"ok","anthropic":"ok","webhook":"ok"}} +``` + +Degraded response (missing secret): +```json +{"status":"degraded","version":"1.0.0","secrets":{"github":"missing","anthropic":"ok","webhook":"ok"},"missing":["github"]} +``` +MDEOF + +git add slicecheck/tests/test_health.py slicecheck/README.md +git commit -m "Add tests and README for health endpoint" +git push + +echo "" +echo "✅ Fix pushed. SliceCheck will re-verify in ~10 seconds." +echo "Expected: ✅ PASS" +echo "Watch: https://github.com/$REPO/pulls" diff --git a/demo-sparkles/scenario-2-open-prs.sh b/demo-sparkles/scenario-2-open-prs.sh new file mode 100644 index 0000000..9094fb9 --- /dev/null +++ b/demo-sparkles/scenario-2-open-prs.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# demo/scenario-2-open-prs.sh +# What this proves: current in-flight work, +# including PRs opened during this hackathon session. + +WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" +REPO="neomatrix369/tripwire" + +AUDIT_URL="$WORKER_URL/audit?repo=$REPO&state=open&limit=10" + +echo "Opening audit — open PRs (including PRs from this session)..." +echo "$AUDIT_URL" + +open "$AUDIT_URL" + +# Bonus: show the same repo works with other projects +# Uncomment to demonstrate portability: +# echo "" +# echo "Same Worker, different repo:" +# open "$WORKER_URL/audit?repo=neomatrix369/rag-params-finder&state=closed&limit=5" diff --git a/demo-sparkles/scenario-3-closed-prs.sh b/demo-sparkles/scenario-3-closed-prs.sh new file mode 100644 index 0000000..0d4c4e7 --- /dev/null +++ b/demo-sparkles/scenario-3-closed-prs.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# demo/scenario-3-closed-prs.sh +# What this proves: SliceCheck learns from history. +# Any repo, any past PRs, no webhook needed. + +WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" +REPO="neomatrix369/tripwire" + +AUDIT_URL="$WORKER_URL/audit?repo=$REPO&state=closed&limit=8" + +echo "Opening retrospective audit — closed PRs..." +echo "$AUDIT_URL" + +# macOS +open "$AUDIT_URL" + +# Linux alternative: +# xdg-open "$AUDIT_URL" + +# Or show raw in terminal while browser loads: +echo "" +echo "Raw summary (while browser loads):" +curl -s "$AUDIT_URL" | python3 -c " +import sys, re +html = sys.stdin.read() +# Extract text between tags for terminal preview +text = re.sub(r'<[^>]+>', ' ', html) +text = re.sub(r'\s+', ' ', text) +print(text[:800]) +" diff --git a/docs/plan/PROGRESS.md b/docs/plan/PROGRESS.md index 7bce5e0..8dcddbd 100644 --- a/docs/plan/PROGRESS.md +++ b/docs/plan/PROGRESS.md @@ -219,6 +219,16 @@ Plan", 2026-08-15). Governance blocks *merge*, not prototyping. 5. Before ✅: confirm Closing rule in GATE_CONTRACT (all checks / waivers, evidence PASS, review, merge) 6. Then: status ✅, completed date, advance Execution order; never ✅ from 🔀 without merge +## Slice: SliceCheck health endpoint +Goal: Add GET /health endpoint to the SliceCheck Worker that returns +the status of all configured secrets and the service version. + +Acceptance criteria: +- [ ] GET /health returns JSON: {"status":"ok","version":"1.0.0","secrets":{"github":"ok","anthropic":"ok","webhook":"ok"}} +- [ ] Returns {"status":"degraded", "missing":[...]} if any secret is absent +- [ ] Unit tests cover healthy state and each degraded variant +- [ ] Endpoint documented in slicecheck/README.md under a Health Check section + ## Skill Execution Log | Date | Branch | Skill | Slice | Outcome | Notes | |------|--------|-------|-------|---------|-------| From 07ceba3e2e6bb0fea8e00898878c8b2f8e0ed755 Mon Sep 17 00:00:00 2001 From: Mani Sarkar Date: Wed, 2 Sep 2026 20:28:41 +0100 Subject: [PATCH 2/5] Adding the demo folder with updated shell scripts --- .gitignore | 2 + demo-sparkles/preflight.sh | 2 +- demo-sparkles/scenario-1-create-pr.sh | 2 +- demo-sparkles/scenario-2-open-prs.sh | 2 +- demo-sparkles/scenario-3-closed-prs.sh | 2 +- demo-sparkles/setup-secrets.sh | 211 +++++++++++++++++++++++++ demo/preflight.sh | 63 ++++++++ 7 files changed, 280 insertions(+), 4 deletions(-) create mode 100755 demo-sparkles/setup-secrets.sh create mode 100644 demo/preflight.sh diff --git a/.gitignore b/.gitignore index 6a87c51..60513e9 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,5 @@ tmp/ cli/.stryker-tmp/ cli/reports/ prototypes/model-studio/out + +python_modules/ \ No newline at end of file diff --git a/demo-sparkles/preflight.sh b/demo-sparkles/preflight.sh index 9fdb376..8222fe6 100644 --- a/demo-sparkles/preflight.sh +++ b/demo-sparkles/preflight.sh @@ -4,7 +4,7 @@ set -e -WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" # ← fill in after wrangler deploy +WORKER_URL="https://slicecheck.sadhak001.workers.dev" REPO="neomatrix369/tripwire" GITHUB_TOKEN="${GITHUB_TOKEN:?Set GITHUB_TOKEN env var}" diff --git a/demo-sparkles/scenario-1-create-pr.sh b/demo-sparkles/scenario-1-create-pr.sh index 8cfa266..a6b0082 100644 --- a/demo-sparkles/scenario-1-create-pr.sh +++ b/demo-sparkles/scenario-1-create-pr.sh @@ -6,7 +6,7 @@ set -e -WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" +WORKER_URL="https://slicecheck.sadhak001.workers.dev" REPO="neomatrix369/tripwire" BRANCH="demo/slicecheck-health-$(date +%s)" diff --git a/demo-sparkles/scenario-2-open-prs.sh b/demo-sparkles/scenario-2-open-prs.sh index 9094fb9..8837c75 100644 --- a/demo-sparkles/scenario-2-open-prs.sh +++ b/demo-sparkles/scenario-2-open-prs.sh @@ -3,7 +3,7 @@ # What this proves: current in-flight work, # including PRs opened during this hackathon session. -WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" +WORKER_URL="https://slicecheck.sadhak001.workers.dev" REPO="neomatrix369/tripwire" AUDIT_URL="$WORKER_URL/audit?repo=$REPO&state=open&limit=10" diff --git a/demo-sparkles/scenario-3-closed-prs.sh b/demo-sparkles/scenario-3-closed-prs.sh index 0d4c4e7..4422039 100644 --- a/demo-sparkles/scenario-3-closed-prs.sh +++ b/demo-sparkles/scenario-3-closed-prs.sh @@ -3,7 +3,7 @@ # What this proves: SliceCheck learns from history. # Any repo, any past PRs, no webhook needed. -WORKER_URL="https://slicecheck.YOUR_ACCOUNT.workers.dev" +WORKER_URL="https://slicecheck.sadhak001.workers.dev" REPO="neomatrix369/tripwire" AUDIT_URL="$WORKER_URL/audit?repo=$REPO&state=closed&limit=8" diff --git a/demo-sparkles/setup-secrets.sh b/demo-sparkles/setup-secrets.sh new file mode 100755 index 0000000..1634883 --- /dev/null +++ b/demo-sparkles/setup-secrets.sh @@ -0,0 +1,211 @@ +#!/bin/bash +# demo-sparkles/setup-secrets.sh +# Resolve SliceCheck Worker secrets at runtime (sign in when needed) and +# upload them with wrangler — no manual paste into `wrangler secret put`. +# +# Sources: +# GITHUB_TOKEN — gh auth (login/refresh) → gh auth token +# GITHUB_WEBHOOK_SECRET — reused from env / secrets/ cache, else generated +# ANTHROPIC_API_KEY — env, else interactive console.anthropic.com flow +# +# Usage: +# bash demo-sparkles/setup-secrets.sh +# WORKER_NAME=slicecheck bash demo-sparkles/setup-secrets.sh + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +WORKER_NAME="${WORKER_NAME:-slicecheck}" +WORKER_DIR="${WORKER_DIR:-$REPO_ROOT/slicecheck}" +WEBHOOK_SECRET_CACHE="${WEBHOOK_SECRET_CACHE:-$REPO_ROOT/secrets/slicecheck-webhook-secret}" +ANTHROPIC_CONSOLE_URL="https://console.anthropic.com/settings/keys" + +redact() { + local value="$1" + local len=${#value} + if [ "$len" -le 8 ]; then + echo "********" + else + echo "${value:0:4}…${value: -4} (len=$len)" + fi +} + +need_cmd() { + command -v "$1" >/dev/null 2>&1 || { + echo "❌ Required command not found: $1" + exit 1 + } +} + +wrangler_cmd() { + if command -v wrangler >/dev/null 2>&1; then + wrangler "$@" + else + need_cmd npx + npx --yes wrangler "$@" + fi +} + +put_secret() { + local name="$1" + local value="$2" + printf '%s' "$value" | wrangler_cmd secret put "$name" --name "$WORKER_NAME" + echo " ✅ $name → $(redact "$value")" +} + +echo "━━━ SliceCheck — setup Worker secrets ━━━" +echo "Worker: $WORKER_NAME" +echo "" + +need_cmd gh +need_cmd openssl +need_cmd python3 + +# ── 1. Cloudflare auth ────────────────────────────────────────────── +echo "[1] Cloudflare (wrangler) auth..." + +wrangler_creds_present() { + # API token in env counts as authenticated — never open a browser login. + if [ -n "${CLOUDFLARE_API_TOKEN:-}" ] || [ -n "${CLOUDFLARE_API_KEY:-}" ]; then + return 0 + fi + # OAuth session from a prior `wrangler login`. + local conf + for conf in \ + "${XDG_CONFIG_HOME:-$HOME/.config}/wrangler/config/default.toml" \ + "$HOME/Library/Preferences/.wrangler/config/default.toml" \ + "$HOME/.wrangler/config/default.toml" + do + if [ -f "$conf" ] && grep -Eq '^[[:space:]]*oauth_token[[:space:]]*=' "$conf"; then + return 0 + fi + done + return 1 +} + +if wrangler_creds_present; then + echo " ✅ Already signed in (local wrangler credentials found) — skipping login" +elif wrangler_cmd whoami 2>/dev/null | grep -Eqi 'Account Name|Email:|authenticated'; then + echo " ✅ Already signed in (wrangler whoami) — skipping login" +else + echo " → No Cloudflare credentials found — opening wrangler login..." + wrangler_cmd login + echo " ✅ Signed in" +fi + +# ── 2. GitHub token via gh ─────────────────────────────────────────── +echo "[2] GitHub token..." +GITHUB_TOKEN_VALUE="${GITHUB_TOKEN:-}" +GH_SCOPES="repo,read:org,admin:repo_hook" + +github_token_ok() { + local token="$1" + local code + code=$(curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: Bearer $token" \ + -H "Accept: application/vnd.github+json" \ + https://api.github.com/user || true) + [ "$code" = "200" ] +} + +if [ -n "$GITHUB_TOKEN_VALUE" ] && github_token_ok "$GITHUB_TOKEN_VALUE"; then + echo " ✅ Using GITHUB_TOKEN from environment ($(redact "$GITHUB_TOKEN_VALUE"))" +else + if [ -n "$GITHUB_TOKEN_VALUE" ]; then + echo " → Env GITHUB_TOKEN rejected by API — falling back to gh auth" + fi + + if ! gh auth status -h github.com >/dev/null 2>&1; then + echo " → GitHub CLI not authenticated — browser login ($GH_SCOPES)..." + gh auth login -h github.com -p https -w -s "$GH_SCOPES" + fi + + GITHUB_TOKEN_VALUE="$(gh auth token 2>/dev/null || true)" + if [ -z "$GITHUB_TOKEN_VALUE" ] || ! github_token_ok "$GITHUB_TOKEN_VALUE"; then + echo " → Token missing/invalid — refresh then login if needed..." + gh auth refresh -h github.com -s "$GH_SCOPES" 2>/dev/null || \ + gh auth login -h github.com -p https -w -s "$GH_SCOPES" + GITHUB_TOKEN_VALUE="$(gh auth token)" + fi + + if ! github_token_ok "$GITHUB_TOKEN_VALUE"; then + echo "❌ GitHub token still invalid after sign-in" + exit 1 + fi + echo " ✅ Resolved via gh ($(redact "$GITHUB_TOKEN_VALUE"))" +fi + +# ── 3. Webhook secret (stable across re-runs) ──────────────────────── +echo "[3] GitHub webhook secret..." +GITHUB_WEBHOOK_SECRET_VALUE="${GITHUB_WEBHOOK_SECRET:-}" + +if [ -z "$GITHUB_WEBHOOK_SECRET_VALUE" ] && [ -f "$WEBHOOK_SECRET_CACHE" ]; then + GITHUB_WEBHOOK_SECRET_VALUE="$(tr -d '[:space:]' < "$WEBHOOK_SECRET_CACHE")" + echo " ✅ Reusing cached secret at $WEBHOOK_SECRET_CACHE ($(redact "$GITHUB_WEBHOOK_SECRET_VALUE"))" +fi + +if [ -z "$GITHUB_WEBHOOK_SECRET_VALUE" ]; then + GITHUB_WEBHOOK_SECRET_VALUE="slicecheck-$(openssl rand -hex 16)" + mkdir -p "$(dirname "$WEBHOOK_SECRET_CACHE")" + printf '%s\n' "$GITHUB_WEBHOOK_SECRET_VALUE" > "$WEBHOOK_SECRET_CACHE" + chmod 600 "$WEBHOOK_SECRET_CACHE" + echo " ✅ Generated + cached at $WEBHOOK_SECRET_CACHE ($(redact "$GITHUB_WEBHOOK_SECRET_VALUE"))" +fi + +if [ "${#GITHUB_WEBHOOK_SECRET_VALUE}" -lt 20 ]; then + echo "❌ GITHUB_WEBHOOK_SECRET must be at least 20 characters" + exit 1 +fi + +# ── 4. Anthropic API key ───────────────────────────────────────────── +echo "[4] Anthropic API key..." +ANTHROPIC_API_KEY_VALUE="${ANTHROPIC_API_KEY:-}" + +if [ -z "$ANTHROPIC_API_KEY_VALUE" ]; then + echo " → ANTHROPIC_API_KEY not in environment." + echo " Opening Anthropic console — create/copy an API key, then paste below." + if command -v open >/dev/null 2>&1; then + open "$ANTHROPIC_CONSOLE_URL" >/dev/null 2>&1 || true + elif command -v xdg-open >/dev/null 2>&1; then + xdg-open "$ANTHROPIC_CONSOLE_URL" >/dev/null 2>&1 || true + else + echo " Visit: $ANTHROPIC_CONSOLE_URL" + fi + # Read from the controlling terminal so piping this script still works. + if [ -r /dev/tty ]; then + printf " Paste ANTHROPIC_API_KEY: " >/dev/tty + IFS= read -r ANTHROPIC_API_KEY_VALUE .workers.dev/webhook" +echo " Content type: application/json" +echo " Secret: (value printed above)" +echo " Events: Pull requests" diff --git a/demo/preflight.sh b/demo/preflight.sh new file mode 100644 index 0000000..f2ecc77 --- /dev/null +++ b/demo/preflight.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# demo/preflight.sh — run at 20:40, before code freeze +# Confirms every dependency for all three scenarios is green + +set -e + +WORKER_URL="https://slicecheck.sadhak001.workers.dev" +REPO="neomatrix369/tripwire" +GITHUB_TOKEN="${GITHUB_TOKEN:?Set GITHUB_TOKEN env var}" + +echo "━━━ SliceCheck Demo Preflight ━━━" +echo "" + +# 1. Worker is live +echo -n "[1] Worker reachable... " +STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$WORKER_URL/") +[ "$STATUS" = "200" ] && echo "✅ $WORKER_URL" || echo "❌ Got HTTP $STATUS — check wrangler deploy" + +# 2. Audit endpoint returns HTML +echo -n "[2] Audit endpoint (closed PRs)... " +AUDIT=$(curl -s "$WORKER_URL/audit?repo=$REPO&state=closed&limit=3") +echo "$AUDIT" | grep -q "SliceCheck" && echo "✅ Returns HTML" || echo "❌ No SliceCheck in response — check Worker logs" + +# 3. Audit endpoint (open PRs) +echo -n "[3] Audit endpoint (open PRs)... " +AUDIT_OPEN=$(curl -s "$WORKER_URL/audit?repo=$REPO&state=open&limit=5") +echo "$AUDIT_OPEN" | grep -q "SliceCheck" && echo "✅ Returns HTML" || echo "❌ Failed" + +# 4. GitHub token has repo access +echo -n "[4] GitHub token — can read closed PRs... " +PR_COUNT=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://api.github.com/repos/$REPO/pulls?state=closed&per_page=3" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))") +[ "$PR_COUNT" -gt "0" ] && echo "✅ $PR_COUNT closed PRs found" || echo "❌ 0 PRs returned — check token scope (needs repo)" + +# 5. Webhook registered +echo -n "[5] Webhook registered on repo... " +HOOKS=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://api.github.com/repos/$REPO/hooks" | python3 -c \ + "import sys,json; hooks=json.load(sys.stdin); print(next((h['config']['url'] for h in hooks if 'slicecheck' in h['config'].get('url','')), 'NOT FOUND'))") +echo "$HOOKS" | grep -q "slicecheck" && echo "✅ $HOOKS" || echo "⚠️ Not found — webhook scenario won't work. Register in GitHub → Repo → Settings → Webhooks" + +# 6. gh CLI authenticated +echo -n "[6] gh CLI authenticated... " +gh auth status &>/dev/null && echo "✅" || echo "❌ Run: gh auth login" + +# 7. Demo branch doesn't already exist (clean state) +echo -n "[7] Demo branch clean... " +git fetch --quiet +git branch -r | grep -q "demo/slicecheck-health" && echo "⚠️ Old demo branch exists — run: git push origin --delete demo/slicecheck-health" || echo "✅" + +# 8. PROGRESS.md has the demo slice +echo -n "[8] PROGRESS.md has demo slice... " +grep -q "SliceCheck health endpoint" PROGRESS.md && echo "✅" || echo "❌ Add the demo slice to PROGRESS.md first" + +# 9. Fallback GIF exists +echo -n "[9] Fallback GIF recorded... " +ls demo/fallback-*.gif &>/dev/null && echo "✅" || echo "⚠️ No fallback GIF found — run scenario 1 now and record it with Kap" + +echo "" +echo "━━━ Preflight complete ━━━" +echo "AUDIT URL (closed): $WORKER_URL/audit?repo=$REPO&state=closed&limit=5" +echo "AUDIT URL (open): $WORKER_URL/audit?repo=$REPO&state=open&limit=5" +echo "WORKER HEALTH: $WORKER_URL/" \ No newline at end of file From f999e4c9f554d0949b71b70f4a2db31cdede889f Mon Sep 17 00:00:00 2001 From: Mani Sarkar Date: Thu, 3 Sep 2026 00:56:33 +0100 Subject: [PATCH 3/5] style: add trailing newlines so pre-push end-of-file-fixer can pass HEAD lacked a final newline in .gitignore and demo/preflight.sh. The hook auto-fixed them, then conflicted with the same unstaged working-tree change and rolled back, blocking the push. --- .gitignore | 2 +- demo/preflight.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 60513e9..9df0a11 100644 --- a/.gitignore +++ b/.gitignore @@ -65,4 +65,4 @@ cli/.stryker-tmp/ cli/reports/ prototypes/model-studio/out -python_modules/ \ No newline at end of file +python_modules/ diff --git a/demo/preflight.sh b/demo/preflight.sh index f2ecc77..8222fe6 100644 --- a/demo/preflight.sh +++ b/demo/preflight.sh @@ -60,4 +60,4 @@ echo "" echo "━━━ Preflight complete ━━━" echo "AUDIT URL (closed): $WORKER_URL/audit?repo=$REPO&state=closed&limit=5" echo "AUDIT URL (open): $WORKER_URL/audit?repo=$REPO&state=open&limit=5" -echo "WORKER HEALTH: $WORKER_URL/" \ No newline at end of file +echo "WORKER HEALTH: $WORKER_URL/" From 70a46c53754b359ad4232edbd0eb8a680c9d47b9 Mon Sep 17 00:00:00 2001 From: Mani Sarkar Date: Thu, 3 Sep 2026 00:58:05 +0100 Subject: [PATCH 4/5] chore(demo): remove duplicate demo/preflight.sh SliceCheck preflight lives in demo-sparkles/; the extra demo/ copy was unused and kept colliding with hook auto-fixes. --- demo/preflight.sh | 63 ----------------------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 demo/preflight.sh diff --git a/demo/preflight.sh b/demo/preflight.sh deleted file mode 100644 index 8222fe6..0000000 --- a/demo/preflight.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -# demo/preflight.sh — run at 20:40, before code freeze -# Confirms every dependency for all three scenarios is green - -set -e - -WORKER_URL="https://slicecheck.sadhak001.workers.dev" -REPO="neomatrix369/tripwire" -GITHUB_TOKEN="${GITHUB_TOKEN:?Set GITHUB_TOKEN env var}" - -echo "━━━ SliceCheck Demo Preflight ━━━" -echo "" - -# 1. Worker is live -echo -n "[1] Worker reachable... " -STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$WORKER_URL/") -[ "$STATUS" = "200" ] && echo "✅ $WORKER_URL" || echo "❌ Got HTTP $STATUS — check wrangler deploy" - -# 2. Audit endpoint returns HTML -echo -n "[2] Audit endpoint (closed PRs)... " -AUDIT=$(curl -s "$WORKER_URL/audit?repo=$REPO&state=closed&limit=3") -echo "$AUDIT" | grep -q "SliceCheck" && echo "✅ Returns HTML" || echo "❌ No SliceCheck in response — check Worker logs" - -# 3. Audit endpoint (open PRs) -echo -n "[3] Audit endpoint (open PRs)... " -AUDIT_OPEN=$(curl -s "$WORKER_URL/audit?repo=$REPO&state=open&limit=5") -echo "$AUDIT_OPEN" | grep -q "SliceCheck" && echo "✅ Returns HTML" || echo "❌ Failed" - -# 4. GitHub token has repo access -echo -n "[4] GitHub token — can read closed PRs... " -PR_COUNT=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ - "https://api.github.com/repos/$REPO/pulls?state=closed&per_page=3" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))") -[ "$PR_COUNT" -gt "0" ] && echo "✅ $PR_COUNT closed PRs found" || echo "❌ 0 PRs returned — check token scope (needs repo)" - -# 5. Webhook registered -echo -n "[5] Webhook registered on repo... " -HOOKS=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ - "https://api.github.com/repos/$REPO/hooks" | python3 -c \ - "import sys,json; hooks=json.load(sys.stdin); print(next((h['config']['url'] for h in hooks if 'slicecheck' in h['config'].get('url','')), 'NOT FOUND'))") -echo "$HOOKS" | grep -q "slicecheck" && echo "✅ $HOOKS" || echo "⚠️ Not found — webhook scenario won't work. Register in GitHub → Repo → Settings → Webhooks" - -# 6. gh CLI authenticated -echo -n "[6] gh CLI authenticated... " -gh auth status &>/dev/null && echo "✅" || echo "❌ Run: gh auth login" - -# 7. Demo branch doesn't already exist (clean state) -echo -n "[7] Demo branch clean... " -git fetch --quiet -git branch -r | grep -q "demo/slicecheck-health" && echo "⚠️ Old demo branch exists — run: git push origin --delete demo/slicecheck-health" || echo "✅" - -# 8. PROGRESS.md has the demo slice -echo -n "[8] PROGRESS.md has demo slice... " -grep -q "SliceCheck health endpoint" PROGRESS.md && echo "✅" || echo "❌ Add the demo slice to PROGRESS.md first" - -# 9. Fallback GIF exists -echo -n "[9] Fallback GIF recorded... " -ls demo/fallback-*.gif &>/dev/null && echo "✅" || echo "⚠️ No fallback GIF found — run scenario 1 now and record it with Kap" - -echo "" -echo "━━━ Preflight complete ━━━" -echo "AUDIT URL (closed): $WORKER_URL/audit?repo=$REPO&state=closed&limit=5" -echo "AUDIT URL (open): $WORKER_URL/audit?repo=$REPO&state=open&limit=5" -echo "WORKER HEALTH: $WORKER_URL/" From c8d20c10099ccfe9da01a402d34c251634ab6b31 Mon Sep 17 00:00:00 2001 From: Mani Sarkar Date: Thu, 3 Sep 2026 01:30:43 +0100 Subject: [PATCH 5/5] chore(demo-sparkles): add teardown script for Worker secrets Undo setup-secrets.sh by deleting Cloudflare Worker secrets and clearing the local webhook-secret cache. --- demo-sparkles/teardown-secrets.sh | 128 ++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100755 demo-sparkles/teardown-secrets.sh diff --git a/demo-sparkles/teardown-secrets.sh b/demo-sparkles/teardown-secrets.sh new file mode 100755 index 0000000..8feafba --- /dev/null +++ b/demo-sparkles/teardown-secrets.sh @@ -0,0 +1,128 @@ +#!/bin/bash +# demo-sparkles/teardown-secrets.sh +# Undo demo-sparkles/setup-secrets.sh: +# 1. Delete GITHUB_TOKEN / GITHUB_WEBHOOK_SECRET / ANTHROPIC_API_KEY from Cloudflare +# 2. Remove the local demo-sparkles webhook-secret cache +# +# Does NOT revoke gh / Anthropic / Cloudflare logins — only the Worker secrets +# and the local cache created by setup. +# +# Usage: +# bash demo-sparkles/teardown-secrets.sh +# WORKER_NAME=slicecheck bash demo-sparkles/teardown-secrets.sh +# YES=1 bash demo-sparkles/teardown-secrets.sh # skip confirmation + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +WORKER_NAME="${WORKER_NAME:-slicecheck}" +WORKER_DIR="${WORKER_DIR:-$REPO_ROOT/slicecheck}" +WEBHOOK_SECRET_CACHE="${WEBHOOK_SECRET_CACHE:-$REPO_ROOT/secrets/slicecheck-webhook-secret}" +SECRET_NAMES=(GITHUB_TOKEN GITHUB_WEBHOOK_SECRET ANTHROPIC_API_KEY) + +need_cmd() { + command -v "$1" >/dev/null 2>&1 || { + echo "❌ Required command not found: $1" + exit 1 + } +} + +wrangler_cmd() { + if command -v wrangler >/dev/null 2>&1; then + wrangler "$@" + else + need_cmd npx + npx --yes wrangler "$@" + fi +} + +wrangler_creds_present() { + if [ -n "${CLOUDFLARE_API_TOKEN:-}" ] || [ -n "${CLOUDFLARE_API_KEY:-}" ]; then + return 0 + fi + local conf + for conf in \ + "${XDG_CONFIG_HOME:-$HOME/.config}/wrangler/config/default.toml" \ + "$HOME/Library/Preferences/.wrangler/config/default.toml" \ + "$HOME/.wrangler/config/default.toml" + do + if [ -f "$conf" ] && grep -Eq '^[[:space:]]*oauth_token[[:space:]]*=' "$conf"; then + return 0 + fi + done + return 1 +} + +delete_secret() { + local name="$1" + # wrangler prompts for confirmation; answer yes non-interactively. + if printf 'y\n' | wrangler_cmd secret delete "$name" --name "$WORKER_NAME"; then + echo " ✅ Deleted Cloudflare secret: $name" + else + echo " ⚠️ Could not delete $name (may already be absent)" + fi +} + +echo "━━━ SliceCheck — teardown Worker secrets ━━━" +echo "Worker: $WORKER_NAME" +echo "Will remove from Cloudflare: ${SECRET_NAMES[*]}" +echo "Will remove local cache: $WEBHOOK_SECRET_CACHE" +echo "" + +if [ "${YES:-0}" != "1" ]; then + if [ -r /dev/tty ]; then + printf "Proceed? [y/N] " >/dev/tty + IFS= read -r reply /dev/null | grep -Eqi 'Account Name|Email:|authenticated'; then + echo " ✅ Already signed in — skipping login" +else + echo " → No Cloudflare credentials found — opening wrangler login..." + wrangler_cmd login + echo " ✅ Signed in" +fi + +# ── 2. Delete secrets on the Worker ────────────────────────────────── +echo "[2] Deleting secrets from Cloudflare Worker '$WORKER_NAME'..." +if [ -d "$WORKER_DIR" ]; then + cd "$WORKER_DIR" +fi + +for secret_name in "${SECRET_NAMES[@]}"; do + delete_secret "$secret_name" +done + +# ── 3. Remove local demo-sparkles cache ────────────────────────────── +echo "[3] Removing local demo-sparkles secret cache..." +if [ -f "$WEBHOOK_SECRET_CACHE" ]; then + rm -f "$WEBHOOK_SECRET_CACHE" + echo " ✅ Removed $WEBHOOK_SECRET_CACHE" +else + echo " ℹ️ No cache file at $WEBHOOK_SECRET_CACHE" +fi + +# Drop empty secrets/ dir if we created only this file +if [ -d "$(dirname "$WEBHOOK_SECRET_CACHE")" ] && \ + [ -z "$(ls -A "$(dirname "$WEBHOOK_SECRET_CACHE")" 2>/dev/null || true)" ]; then + rmdir "$(dirname "$WEBHOOK_SECRET_CACHE")" 2>/dev/null || true +fi + +echo "" +echo "━━━ Teardown complete ━━━" +echo "Cloudflare Worker secrets removed; local webhook-secret cache cleared." +echo "Note: gh / Anthropic / wrangler logins were left in place." +echo "If a GitHub repo webhook still points at this Worker, delete it under" +echo " Repo → Settings → Webhooks (or: gh api repos///hooks)"