diff --git a/CLAUDE.md b/CLAUDE.md index 016576b..97a1d05 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -634,8 +634,6 @@ tengu/ │ ├── deployment-guide.md │ ├── api-reference.md │ ├── autonomous-agent.md -│ ├── demo-script.md -│ ├── hn-post.md │ └── contributing.md │ ├── logs/ ← Audit logs (gitignored) diff --git a/docs/demo-script.md b/docs/demo-script.md deleted file mode 100644 index 0ef646f..0000000 --- a/docs/demo-script.md +++ /dev/null @@ -1,163 +0,0 @@ -# Tengu Demo Script — 10–15 min - -**Audience:** Security Director -**Target:** OWASP Juice Shop (`http://juice-shop:3000`) -**Environment:** Docker Compose local (`--profile lab`) -**Mode:** Clean Claude Code session with Tengu via MCP - ---- - -## Pre-Demo (before entering the room) - -```bash -# Start the environment -make docker-lab - -# Confirm everything is up -docker compose ps - -# Verify Juice Shop is reachable (juice-shop is internal to the Docker network) -docker exec $(docker compose ps -q tengu) curl -s http://juice-shop:3000/ | grep -o "OWASP Juice Shop" -``` - -**`tengu.toml` — add the target to the allowlist:** -```toml -[targets] -allowed_hosts = ["juice-shop", "172.20.0.5"] -``` - ---- - -## Phase 0 — Setup (~1 min) - -**What to show:** scope control, available tooling. - -**Prompt:** -``` -Check which pentesting tools are installed and validate that juice-shop is an allowed target. -``` - -Claude calls `check_tools` and `validate_target` — lists available tools and confirms the target is in the allowlist before any action. - -> **Talking point:** "Before any scan, Tengu validates scope. Zero action outside the authorized target." - ---- - -## Phase 1 — Discovery + Vulnerabilities (~5 min) - -**What to show:** Claude orchestrating a full pentest with a single prompt. - -**Prompt:** -``` -Use find_vulns on juice-shop -``` - -Claude follows the `find_vulns` prompt workflow: -1. `nmap_scan` — port scan + service fingerprint (port 3000/tcp open, Node.js) -2. `nuclei_scan` — CVE templates and misconfigurations (severity: medium, high, critical) -3. `nikto_scan` — web server misconfigurations -4. `analyze_headers` — missing security headers (CSP, HSTS, X-Frame-Options) -5. `cve_search` — CVEs for the detected Node.js/Express stack -6. `searchsploit_query` — publicly available exploits - -Among the findings, nuclei/nikto flags the `/rest/products/search` endpoint as suspicious. - -> **Talking point:** "One prompt. Claude fired 6 tools in sequence, correlated the results, and delivered prioritized findings by severity." - ---- - -## Phase 2 — SQLi: Exploitation + Dump (~6 min) - -**What to show:** moving from finding to exploitation with a natural language prompt. - -**Prompt:** -``` -The endpoint /rest/products/search?q=test looks injectable. Confirm the SQLi and dump the Users table — email, password, role. -``` - -Claude calls: -1. `sqlmap_scan` on `http://juice-shop:3000/rest/products/search?q=test` — **UNION SQLi confirmed** (SQLite, 9 columns, parameter `q`) -2. `sqlmap_scan` with `--dump` on the `Users` table → 22 users with email, MD5 hash, and role - -Output: -``` -admin@juice-sh.op | 0192023a7bbd73250516f069df18b500 | admin -jim@juice-sh.op | e541ca7ecf72b8d1286474fc613e5e45 | customer -... -[22 rows total] -``` - -> **Talking point:** "From finding to data exfiltration in one message. No manual commands." - ---- - -## Phase 3 — Hash Crack (~2 min) - -**What to show:** real impact — from hash to plaintext password. - -**Prompt:** -``` -Identify and crack this hash from the admin account: 0192023a7bbd73250516f069df18b500 -``` - -Claude calls: -1. `hash_identify` → MD5 confirmed -2. `hash_crack` with rockyou → **`admin123`** in ~3 seconds - -> **Talking point:** "admin@juice-sh.op / admin123. Full access to the admin panel. The full cycle — discovery, exploitation, exfiltration, password cracking — driven by natural language." - ---- - -## Wrap-up (~1 min, if time allows) - -**Prompt:** -``` -Generate an executive summary report of all findings from this assessment. -``` - -Claude calls `generate_report` with the accumulated findings and delivers a structured report with severity ratings, CVSS scores, and remediation recommendations. - ---- - -## Timing Reference - -| Phase | Duration | Cumulative | -|-------|----------|------------| -| 0. Setup | ~1 min | 1 min | -| 1. find_vulns | ~5 min | 6 min | -| 2. SQLi + Dump | ~6 min | 12 min | -| 3. Hash Crack | ~2 min | 14 min | -| Buffer / Q&A | ~1 min | 15 min | - ---- - -## Quick Troubleshooting - -**`sqlmap` does not detect injection:** -Increase the level directly in the prompt: -``` -Run sqlmap_scan on http://juice-shop:3000/rest/products/search?q=test with level=5 and risk=3 -``` - -**`Target not allowed` on start:** -```bash -TENGU_ALLOWED_HOSTS=juice-shop,172.20.0.5 docker compose up -d -``` - -**Claude cannot see Tengu tools:** -Check in Claude Code: `/mcp` → should show `tengu (connected)` - -**`hash_crack` does not find the password:** -```bash -docker exec ls /usr/share/wordlists/rockyou.txt -``` - ---- - -## Pre-Demo Checklist - -- [ ] `docker compose --profile lab up -d` running -- [ ] `tengu.toml` with `allowed_hosts = ["juice-shop", "172.20.0.5"]` -- [ ] `http://juice-shop:3000` accessible in the browser -- [ ] Claude Code: `/mcp` shows `tengu (connected)` -- [ ] Clean session open (`claude` in a new window) diff --git a/docs/demo.gif b/docs/demo.gif deleted file mode 100644 index 9b61664..0000000 Binary files a/docs/demo.gif and /dev/null differ diff --git a/docs/hn-post.md b/docs/hn-post.md deleted file mode 100644 index 31c32ba..0000000 --- a/docs/hn-post.md +++ /dev/null @@ -1,80 +0,0 @@ -# Show HN: Tengu — Post for Hacker News - -## Title - -``` -Show HN: Tengu – an open-source MCP server that turns Claude into a pentesting copilot -``` - -## Text - -``` -Hi HN, - -I built Tengu, an open-source MCP server (MIT) that connects Claude to 80 real -pentesting tools — Nmap, Metasploit, SQLMap, Nuclei, Hydra, ZAP, and more. - -You describe what you want ("do a full pentest on 192.168.1.100") and the LLM -chains the right tools automatically: validate_target → whatweb → nmap → nikto → -nuclei → sqlmap → correlate_findings → generate_report. - -What makes it different from "ChatGPT runs nmap": - -- Safety pipeline on every call: input sanitizer (rejects shell metacharacters), - target allowlist, rate limiter, audit logger. shell=True is banned — 74 tests - specifically for command injection. - -- Human-in-the-loop for anything destructive: exploits, brute force, and - kerberoasting require explicit confirmation before execution. - -- Stealth layer: optional Tor/SOCKS5 proxy injection, UA rotation, and timing - jitter — transparent to tool code. - -- Professional reporting: auto-correlates findings across tools, calculates CVSS - risk scores, generates MD/HTML/PDF reports. - -- 2562+ tests, mypy strict, ruff, 90%+ coverage. Not a weekend hack. - -It also ships with 35 guided workflow prompts (full PTES pentest, bug bounty, -AD assessment, cloud audit, compliance checks) and 20 built-in resources -(OWASP Top 10, MITRE ATT&CK, pentest checklists). - -Docker-first: `make docker-build && make docker-up` gets you running. -Practice targets (Juice Shop, DVWA) included via `make docker-lab`. - -Tech: Python 3.12+, FastMCP 2.0, Pydantic v2, structlog, asyncio. - -GitHub: https://github.com/rfunix/tengu - -Happy to answer questions about the security model, MCP integration, or -anything else. -``` - -## Best Time to Post - -| Window | UTC | BRT (Brasília) | Breakout Rate | -|--------|-----|----------------|---------------| -| **#1 (best)** | Sunday 11:00–14:00 UTC | Sunday 08:00–11:00 BRT | ~14% | -| **#2** | Saturday 20:00–02:00 UTC | Saturday 17:00–23:00 BRT | ~15.7% | -| **#3 (absolute peak)** | Sunday 12:00 UTC | Sunday 09:00 BRT | 12.2% | - -**Recommendation: Sunday at 09:00 BRT (12:00 UTC / 08:00 AM EDT)** - -- Sunday has 20–30% higher breakout chance than weekdays -- 12:00 UTC is the single best-performing hour historically -- Aligns with early morning on the US East Coast (primary HN audience) -- Less competition from corporate posts on weekends - -**Backup:** Saturday at 17:00 BRT (20:00 UTC). - -## Tips - -1. Do not ask anyone for upvotes — HN detects and penalizes vote rings. -2. Reply to comments quickly in the first 2 hours — it boosts ranking. -3. Prepare answers for predictable objections: - - *"Isn't giving an LLM access to exploit tools dangerous?"* - → Safety pipeline, allowlist, human-in-the-loop gate for destructive actions. - - *"How is this different from AutoGPT + bash?"* - → MCP protocol, structured tool calls, no shell=True, 74 injection tests. - - *"Why not just use Metasploit/Caldera?"* - → LLM as strategist, not rigid automation; natural language → multi-tool chains. diff --git a/docs/tengu-demo-claude-code.cast b/docs/tengu-demo-claude-code.cast deleted file mode 100644 index bdecdb4..0000000 --- a/docs/tengu-demo-claude-code.cast +++ /dev/null @@ -1,88 +0,0 @@ -{"version":3,"term":{"cols":149,"rows":40,"type":"tmux-256color","version":"tmux 3.6a","theme":{"fg":"#cdd6f4","bg":"#1e1e2e","palette":"#45475a:#f38ba8:#a6e3a1:#f9e2af:#89b4fa:#f5c2e7:#94e2d5:#bac2de:#585b70:#f38ba8:#a6e3a1:#f9e2af:#89b4fa:#f5c2e7:#94e2d5:#a6adc8"}},"timestamp":1772561017,"idle_time_limit":5.0,"command":"tmux attach-session -t tengu-demo","title":"Tengu + Claude Code — Pentesting Juice Shop","env":{"SHELL":"/bin/zsh"}} -[0.014, "o", "\u001b[?1049h\u001b[?1h\u001b=\u001b[H\u001b[J\u001b[34h\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b[?2031h\u001b[?996n\u001b[m\u000f\u001b[34h\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;40r\u001b[c\u001b[>c\u001b[>q\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;23H\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006h\u001b[?1000h\u001b[?1002h"] -[0.000, "o", "\u001b]0;tengu-demo:1:zsh - \"mac.lan\" \u0007\u001b[?25l\u001b[32m\u001b[1m\u001b[H➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[34h\u001b[?25h\u001b[1;23H\u001b[m\u000f\u001b[34h\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;40r"] -[0.001, "o", "\u001b[?25l\u001b[32m\u001b[1m\u001b[1;1H➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[34h\u001b[?25h\u001b[1;23H\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006h\u001b[?1000h\u001b[?1002h"] -[0.008, "o", "\u001b[?7727h\u001b[m\u000f\u001b[34h\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;40r\u001b[?7727h\u001b[m\u000f\u001b[34h\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;40r\u001b[?7727h\u001b[m\u000f\u001b[34h\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;40r\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;23H\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006h\u001b[?1000h\u001b[?1002h"] -[0.000, "o", "\u001b[?25l\u001b[32m\u001b[1m\u001b[H➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[34h\u001b[?25h\u001b[1;23H"] -[2.996, "o", "c"] -[0.142, "o", "\bcl"] -[0.113, "o", "a"] -[0.086, "o", "u"] -[0.093, "o", "d"] -[0.069, "o", "e"] -[0.082, "o", " "] -[0.153, "o", "-"] -[0.108, "o", "-"] -[0.111, "o", "d"] -[0.109, "o", "a"] -[0.108, "o", "n"] -[0.117, "o", "g"] -[0.115, "o", "e"] -[0.099, "o", "r"] -[0.082, "o", "o"] -[0.116, "o", "u"] -[0.074, "o", "s"] -[0.066, "o", "l"] -[0.068, "o", "y"] -[0.096, "o", "-"] -[0.075, "o", "s"] -[0.107, "o", "k"] -[0.087, "o", "i"] -[0.093, "o", "p"] -[0.108, "o", "-"] -[0.090, "o", "p"] -[0.077, "o", "e"] -[0.107, "o", "r"] -[0.093, "o", "m"] -[0.084, "o", "i"] -[0.091, "o", "s"] -[0.074, "o", "s"] -[0.108, "o", "i"] -[0.102, "o", "o"] -[0.078, "o", "n"] -[0.071, "o", "s"] -[0.635, "o", "\r\n"] -[0.305, "o", "\u001b[?25l"] -[0.207, "o", "\u001b]0;tengu-demo:1:2.1.63 - \"mac.lan\" \u0007"] -[0.200, "o", "\u001b[91m\u001b[2m─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[3;2H\u001b[m\u000f\u001b[91m\u001b[1mWARNING:\u001b[CClaude\u001b[CCode\u001b[Crunning\u001b[Cin\u001b[CBypass\u001b[CPermissions\u001b[Cmode\u001b[5;2H\u001b[m\u000fIn\u001b[CBypass\u001b[CPermissions\u001b[Cmode,\u001b[CClaude\u001b[CCode\u001b[Cwill\u001b[Cnot\u001b[Cask\u001b[Cfor\u001b[Cyour\u001b[Capproval\u001b[Cbefore\u001b[Crunning\u001b[Cpotentially\u001b[Cdangerous\u001b[Ccommands.\u001b[6;2HThis\u001b[Cmode\u001b[Cshould\u001b[Conly\u001b[Cbe\u001b[Cused\u001b[Cin\u001b[Ca\u001b[Csandboxed\u001b[Ccontainer/VM\u001b[Cthat\u001b[Chas\u001b[Crestricted\u001b[Cinternet\u001b[Caccess\u001b[Cand\u001b[Ccan\u001b[Ceasily\u001b[Cbe\u001b[Crestored\u001b[Cif\u001b[Cdamaged.\u001b[8;2HBy\u001b[Cproceeding,\u001b[Cyou\u001b[Caccept\u001b[Call\u001b[Cresponsibility"] -[0.000, "o", "\u001b[Cfor\u001b[Cactions\u001b[Ctaken\u001b[Cwhile\u001b[Crunning\u001b[Cin\u001b[CBypass\u001b[CPermissions\u001b[Cmode.\u001b[10;2Hhttps://code.claude.com/docs/en/security\u001b[12;2H\u001b[94m❯\u001b[C\u001b[m\u000f\u001b[37m1.\u001b[C\u001b[94mNo,\u001b[Cexit\u001b[13;4H\u001b[m\u000f\u001b[37m2.\u001b[C\u001b[39mYes,\u001b[CI\u001b[Caccept\u001b[15;2H\u001b[37m\u001b[3mEnter\u001b[Cto\u001b[Cconfirm\u001b[C·\u001b[CEsc\u001b[Cto\u001b[Ccancel\r\n\u001b[m\u000f"] -[5.563, "o", "\u001b[12;2H \u001b[4CNo, exit\u001b[13;2H\u001b[94m❯\u001b[4CYes, I accept\u001b[16;1H\u001b[m\u000f"] -[1.216, "o", "\u001b[2d \u001b[3;1H\u001b[91m \u001b[39m\u001b[12;1H\u001b[K\r\n\u001b[K\u001b[2B\u001b[K\u001b[3;2H\u001b[91m▐\u001b[40m▛███▜\u001b[49m▌\u001b[39m \u001b[1mClaude Code\u001b[m\u000f \u001b[37mv2.1.63\u001b[39m \r\n\u001b[91m▝▜\u001b[40m█████\u001b[49m▛▘\u001b[2C\u001b[m\u000f\u001b[37mSonnet 4.6 · Claude Max\r\n\u001b[91m ▘▘ ▝▝ \u001b[39m \u001b[C\u001b[37m~/dev/tengu\u001b[C\u001b[39m \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[6;2H \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \r\n\u001b[37m\u001b[2m──────────────────────────────────────────────────────────────────────\u001b[m\u000f"] -[0.000, "o", "\u001b[37m\u001b[2m───────────────────────────────────────────────────────────────────────────────\u001b[8;1H\u001b[m\u000f❯ \u001b[7m \u001b[C\u001b[m\u000f \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \u001b[C \r\n\u001b[37m\u001b[2m─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[10;2H\u001b[m\u000f \u001b[91m⏵⏵ bypass permissions on\u001b[m\u000f\u001b[37m (shift+tab to cycle)\r\n\u001b[39m "] -[0.000, "o", " \u001b[12;1H \u001b[13;1H \u001b[14;1H \u001b[15;1H \u001b[11;1H"] -[0.004, "o", "\u001b]0;tengu-demo:1:2.1.63 - \"✳ Claude Code\" \u0007"] -[31.874, "o", "\u001b[10;3H\u001b[37mPress Ctrl-C again to exit\u001b[39m \r\n"] -[0.438, "o", "\u001b[5A \u001b[7;1H \u001b[8;1H \u001b[9;1H \u001b[10;1H \u001b[11;1H\u001b[K\u001b[5A"] -[0.054, "o", "\u001b]0;tengu-demo:1:2.1.63 - \"\" \u0007\u001b[34h\u001b[?25h"] -[0.021, "o", " \u001b[6;1H"] -[0.004, "o", "\u001b[?25l\u001b[34h\u001b[?25h"] -[0.001, "o", "\r\n\u001b[J\u001bM\u001b[K\u001b[32m\u001b[1m➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K"] -[0.005, "o", "\r\n"] -[0.001, "o", " \u001b[7;1H"] -[0.004, "o", "\u001b[?25l\u001b[34h\u001b[?25h"] -[0.000, "o", "\r\n\u001b[J\u001bM\u001b[K\u001b[31m\u001b[1m➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K"] -[0.161, "o", "\r\n"] -[0.000, "o", " \u001b[8;1H"] -[0.003, "o", "\u001b[?25l\u001b[34h\u001b[?25h"] -[0.001, "o", "\r\n\u001b[J\u001bM\u001b[K\u001b[31m\u001b[1m➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K"] -[0.169, "o", "\r\n"] -[0.000, "o", " \u001b[9;1H"] -[0.004, "o", "\u001b[?25l\u001b[34h\u001b[?25h"] -[0.001, "o", "\r\n\u001b[J\u001bM\u001b[K\u001b[31m\u001b[1m➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K"] -[0.168, "o", "\u001b]0;tengu-demo:1:zsh - \"\" \u0007\u001b[?25l\u001b[34h\u001b[?25h"] -[0.001, "o", "\r\n"] -[0.000, "o", " \u001b[10;1H"] -[0.004, "o", "\u001b[?25l\u001b[34h\u001b[?25h"] -[0.001, "o", "\r\n\u001b[J\u001bM\u001b[K\u001b[31m\u001b[1m➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K"] -[0.156, "o", "\r\n"] -[0.001, "o", " \u001b[11;1H"] -[0.003, "o", "\u001b[?25l\u001b[34h\u001b[?25h"] -[0.001, "o", "\r\n\u001b[J\u001bM\u001b[K\u001b[31m\u001b[1m➜ \u001b[36mtengu\u001b[m\u000f \u001b[34m\u001b[1mgit:(\u001b[31mmain\u001b[34m) \u001b[33m✗\u001b[m\u000f \u001b[K"] -[0.662, "o", "e"] -[0.155, "o", "\bex"] -[0.173, "o", "i"] -[0.119, "o", "t"] -[0.107, "o", "\r\n"] -[0.012, "o", "\u001b[1;40r\u001b[m\u000f\u001b[?1l\u001b>\u001b[H\u001b[J\u001b[34h\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[?2031l"] -[0.001, "o", "[exited]\r\n"] -[0.000, "x", "0"] diff --git a/docs/tengu-demo-opt.gif b/docs/tengu-demo-opt.gif deleted file mode 100644 index d816178..0000000 Binary files a/docs/tengu-demo-opt.gif and /dev/null differ diff --git a/docs/tengu-demo.mp4 b/docs/tengu-demo.mp4 deleted file mode 100644 index 416f8de..0000000 Binary files a/docs/tengu-demo.mp4 and /dev/null differ