deepshell / CLAUDE.md
muralipala1504
docs: document TTS inline code fix (2026-06-15)
ef5846f
|
Raw
History Blame Contribute Delete
10.1 kB
# πŸ’» DeepShell ModUI β€” Developer Reference (CLAUDE.md)
> This file is the AI assistant context document for Claude and other AI tools working on this codebase.
> Keep this in sync with README.md after major changes.
**Live Demo**: https://deepshell.cloud
**HF Spaces**: https://huggingface.co/spaces/muralipala/deepshell
**GitHub**: https://github.com/muralipala1504/deepshell_modui (private)
**Cloudflare Worker**: deepshell-proxy β†’ proxies deepshell.cloud to HF Spaces
## πŸ—οΈ Architecture Overview
- **Frontend**: Vanilla JS, no frameworks, served by FastAPI
- **Backend**: FastAPI + SSE + `/translate` + `/tts` endpoints
- **Translation**: LibreTranslate (self-hosted, en→hi)
- **TTS**: Piper (hi_IN-rohan-medium) + Web Speech API (EN)
- **LLM**: Groq β†’ Cerebras β†’ Ollama
- **Deployment**: HuggingFace Spaces (single container) + docker-compose (self-hosted)
- **Modes**: Assistant (fast answers) + Trainer (structured learning) β€” Dry Run removed (no live terminal in free version)
## πŸ“ Key Files
| File | Purpose |
|------|---------|
| `app.js` | Frontend β€” SSE, TTS, Piper audio, lang selector |
| `index.html` | UI β€” chat, modes, theme, lang dropdown |
| `deepshell-backend/deepshell/__main__.py` | FastAPI β€” SSE + /translate + /tts + security middleware |
| `deepshell-backend/deepshell/llm.py` | LLM clients + prompts |
| `Dockerfile` | Docker Compose image (Piper bundled) |
| `Dockerfile.hf` | HuggingFace Spaces image (Piper + LibreTranslate bundled) |
| `docker-compose.yml` | Self-hosted β€” DeepShell + LibreTranslate sidecar |
| `start.sh` | Start DeepShell + LibreTranslate (webapp mode) |
| `stop.sh` | Stop all services |
| `start_hf.sh` | HF Spaces startup script |
| `requirements-translation.txt` | LibreTranslate version pin |
| `about.html` | About page β€” mission, features, builder, special thanks |
| `contact.html` | Contact page β€” email, GitHub, YouTube links |
## ⚠️ Important Deployment Note
- HF Spaces builds using `Dockerfile` (not `Dockerfile.hf`)
- Always keep both in sync before deploying: `cp Dockerfile.hf Dockerfile`
- `dockerfile: Dockerfile.hf` added to README.md header but HF ignores it β€” direct copy is the working fix
## πŸ”§ Environment Variables
| Variable | Default | Purpose |
|----------|---------|---------|
| `GROQ_API_KEY` | required | Groq LLM API key |
| `PROVIDER` | groq | LLM provider (groq/cerebras/ollama) |
| `PORT` | 8001 (7860 on HF) | Server port |
| `PIPER_BINARY` | ~/piper/piper | Piper TTS binary path |
| `PIPER_VOICE_DIR` | ~/piper/voices | Piper voice models directory |
| `LIBRETRANSLATE_URL` | http://localhost:5000/translate | Translation service URL |
| `CEREBRAS_API_KEY` | optional | Cerebras failover API key |
| `ADMIN_API_KEY` | required | Locks /chat/history endpoint β€” generate with `python3 -c "import secrets; print(secrets.token_hex(32))"` |
| `MAX_TTS_LENGTH` | 500 | Max TTS input characters |
| `MAX_TRANSLATE_LENGTH` | 1000 | Max translation input characters |
| `CORS_ORIGINS` | blank | Extra allowed origins (comma-separated) β€” defaults cover deepshell.cloud + HF Space |
| `DEBUG` | false | Enable debug mode β€” NEVER true in production |
## πŸ”’ Security Architecture (Added 2026-05-29)
### What is hardened
| Layer | Measure |
|-------|---------|
| `/health` | Returns timestamp only β€” no debug info, no internal config exposed |
| `/chat/history` | Locked behind `X-Admin-Key` header β€” returns 401 without valid `ADMIN_API_KEY` |
| `/translate` | Rate limited 30/minute per IP + input validation + language whitelist |
| `/tts` | Rate limited 20/minute per IP + input validation (max 500 chars) + language whitelist |
| `/chat/run-agent-stream` | Rate limited 10/minute per IP |
| `/chat/run-agent` | Rate limited 20/minute per IP |
| CORS | Locked to deepshell.cloud + www.deepshell.cloud + muralipala-deepshell.hf.space only |
| IP Logging | All requests log IP + endpoint + status β€” prompt content NEVER logged |
| Input validation | All endpoints validate via Pydantic v2 field_validator β€” lang whitelist, length caps |
| Language injection | Unsupported lang values rejected with 422 |
| Payload abuse | Oversized payloads rejected with 422 |
| Real IP detection | CF-Connecting-IP β†’ X-Forwarded-For β†’ client.host fallback chain for accurate rate limiting behind Cloudflare |
### ADMIN_API_KEY setup
```bash
# Generate
python3 -c "import secrets; print(secrets.token_hex(32))"
# Local dev
export ADMIN_API_KEY="<generated_key>"
# HF Spaces
# Settings β†’ Variables and Secrets β†’ New Secret β†’ ADMIN_API_KEY
```
### Access /chat/history with admin key
```bash
curl -s https://deepshell.cloud/chat/history \
-H "X-Admin-Key: <your_admin_key>" | python3 -m json.tool
```
### Security test commands
```bash
# Health β€” timestamp only
curl -s https://deepshell.cloud/health | python3 -m json.tool
# History without key β€” must return 401
curl -s https://deepshell.cloud/chat/history | python3 -m json.tool
# Rate limit test β€” 429 after 20 hits
for i in {1..25}; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST https://deepshell.cloud/tts \
-H "Content-Type: application/json" \
-d '{"text": "test", "lang": "hi"}')
echo "Request $i: $STATUS"
done
# Oversized payload β€” must return 422
curl -s -X POST https://deepshell.cloud/tts \
-H "Content-Type: application/json" \
-d "{\"text\": \"$(python3 -c "print('A'*600)")\", \"lang\": \"hi\"}" | python3 -m json.tool
# Language injection β€” must return 422
curl -s -X POST https://deepshell.cloud/tts \
-H "Content-Type: application/json" \
-d '{"text": "test", "lang": "en; rm -rf /"}' | python3 -m json.tool
```
## 🌐 TTS Pipeline
### English
- Web Speech API (browser-native)
- Instantaneous response
- Triggered via Voice ON button
### Hindi (Piper)
- Sentence by sentence for low latency
- 300ms delay on first sentence to prevent cutoff
- Fallback to Web Speech API if backend fails
- Slight delay vs EN β€” expected (translate β†’ Piper generate β†’ audio blob β†’ play)
- βœ… Fixed (2026-06-05): Code blocks now stripped before sending to Piper β€” prose only
- Fix: `app.js` β€” replaced backtick strip with full code block regex + inline code β†’ "code snippet"
- βœ… Fixed (2026-06-15): Inline code spans (`command`) in Trainer responses were being replaced with the spoken phrase "code snippet" β€” repeated 5-9x per response (once per inline backtick in "Breaking it down" / "Pro tip" sections), making EN/HI audio sound broken.
- Fix: `app.js:97` β€” changed `.replace(/`[^`]+`/g, "code snippet")` to `.replace(/`([^`]+)`/g, "$1")`, so TTS now speaks the actual command/text inside inline code instead of a placeholder. Fenced ```bash``` blocks remain fully stripped (line 96, unchanged).
## 🌐 Lang Dropdown Status (2026-06-05)
| Lang | Status |
|------|--------|
| EN | βœ… Live β€” instant |
| HI | βœ… Live β€” slight delay (pipeline: translate + Piper TTS) |
| TA | ⏳ Coming Soon |
| TE | ⏳ Coming Soon |
| AR | ⏳ Coming Soon |
## πŸš€ Deployment Paths
### Webapp (development)
```bash
./start.sh # starts DeepShell + LibreTranslate
./stop.sh
```
### Docker Compose (self-hosted)
```bash
export GROQ_API_KEY=...
export ADMIN_API_KEY=...
docker compose up -d
```
### HuggingFace Spaces
- Branch: `hf-deploy`
- Push: `git push hf hf-deploy:main`
- Single container: Dockerfile.hf (Piper + LibreTranslate bundled)
- Port: 7860
- Secrets: GROQ_API_KEY + CEREBRAS_API_KEY + ADMIN_API_KEY set in HF Space settings
- URL: https://muralipala-deepshell.hf.space
### Custom Domain (deepshell.cloud)
- Registrar: Hostinger (complimentary domain)
- DNS: Cloudflare (nameservers: ingrid.ns.cloudflare.com, wilson.ns.cloudflare.com)
- Cloudflare Worker: deepshell-proxy proxies all traffic to muralipala-deepshell.hf.space
- SSL: Auto-provisioned by Cloudflare (free)
- No HF Pro needed
- Real user IPs passed via CF-Connecting-IP header for accurate rate limiting
## πŸ” Standard Deploy Workflow
```bash
# 1. Make changes on main
git add .
git commit -m "your message"
git push origin main
# 2. Merge to hf-deploy and push to HF
git checkout hf-deploy
git merge main
cp Dockerfile.hf Dockerfile
git add Dockerfile
git commit -m "sync Dockerfile for HF deploy"
git push hf hf-deploy:main
git checkout main
```
## πŸ“§ Email Routing
- `contact@deepshell.cloud` β†’ forwarded to muralidharmpala@gmail.com
- Configured via Cloudflare Email Routing (free)
- MX + SPF + DKIM records auto-added by Cloudflare
## 🎬 SysTelligence YouTube Videos (DeepShell Playlist)
### Trainer Mode Series (2026-06-05)
| Video | URL |
|-------|-----|
| LVM Extend Online | https://youtu.be/nswBYOLCRAM |
| Docker Compose Nginx + PostgreSQL | https://youtu.be/PS6pOot_q8E |
| Kubernetes CrashLoopBackOff | https://youtu.be/CAvrppozzQQ |
| Ansible User Management | https://youtu.be/FRRpX0yyUKw |
- Recorded via OBS (Firefox Classic theme, Window Capture)
- EN TTS only for Trainer series β€” HI fixed after recording
- All added to "DeepShell" playlist on SysTelligence channel
### Next (2026-06-06)
- HN (Hacker News) style videos planned β€” topics TBD
## πŸ—‚οΈ Pending / Next Sprint
- [ ] HN videos β€” record + upload (2026-06-06)
- [ ] TA, TE, AR TTS β€” future sprints
---
---
title: DeepShell
emoji: πŸ’»
colorFrom: green
colorTo: blue
sdk: docker
app_port: 7860
license: mit
short_description: AI-powered DevOps assistant with Hindi TTS
pinned: false
---
## πŸ” SEO & Google Search Console
| Item | Detail |
|------|--------|
| GSC Property | https://www.deepshell.cloud/ |
| Verification | HTML meta tag in `index.html` (line 5) |
| Sitemap | https://www.deepshell.cloud/sitemap.xml (3 pages) |
| Robots | Cloudflare managed robots.txt (Googlebot allowed, AI scrapers blocked) |
| Sitemap endpoint | `GET /sitemap.xml` in `__main__.py` |
| Robots endpoint | `GET /robots.txt` in `__main__.py` (overridden by CF managed) |
> ⚠️ Do NOT remove the GSC meta tag from `index.html` β€” breaks GSC verification
> ⚠️ Do NOT disable CF managed robots.txt β€” protects against AI scrapers