{"id":"6382b9eb-ea04-4fe2-9d33-9953fba64e3b","slug":"trinity-claw","kind":"skill","name":"trinity-claw","summary":"A self-hosted AI agent that thinks, acts, and improves itself – all running privately on your own machine. Browses the web, writes and executes code, manages files, sends emails, monitors URLs, builds","owner":"TrinityClaw","repoUrl":"https://github.com/TrinityClaw/trinity-claw","license":"MIT","licenseTier":"permissive","trust":"community","stars":11,"match":null,"fewStars":false,"format":"skill","createdAt":"2026-03-07T19:42:07.000Z","addedAt":"2026-10-21T10:41:57.703Z","logoUrl":"https://avatars.githubusercontent.com/u/261506174?u=37a0010bb900c9f7713ee66e2cfdf3c41f17b2a2&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools","files-documents","data-analytics"],"tags":["agentic-workflow","ai-agents","automation","localagent","ai","own-your-data","persistant-memory","self-improving-agent"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-25T15:26:16.154Z","sample":false,"url":"https://conduits.dev/tools/trinity-claw","language":"Python","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"---\ntitle: TrinityClaw AI Agent\nemoji: 🦾\ncolorFrom: purple\ncolorTo: blue\nsdk: docker\npinned: false\n---\n\n# TrinityClaw AI Agent\n\nA self-modifying AI agent with persistent memory, dynamic skill creation, and intelligent reasoning capabilities.\n\n---\n\n> ## 🖥️ LOCAL USE ONLY\n>\n> **TrinityClaw is designed for personal local servers — do not deploy it on a VPS or any public-facing server.**\n>\n> The agent API has no rate limiting and no multi-user authentication layer. The `code_executor` and `terminal` skills run arbitrary code inside Docker, and the single `TRINITY_API_KEY` is not sufficient protection for an internet-exposed host. Running this on a public IP without additional firewall rules and a reverse proxy with proper auth could expose your system to unauthorized access.\n>\n> **Recommended setup:** run on your home machine or a local network server, accessed via your LAN or a private VPN (e.g. Tailscale, WireGuard). Do **not** open ports 8001, 8080, or 8090 to the public internet.\n\n---\n\n## ⚠️ Security Notice\n\n> **Use at your own risk.**\n\nTrinityClaw is **secure by design** in its original form:\n- All skills run inside an isolated Docker container with no host access\n- Dynamic skill creation uses AST validation and a module ban-list to block dangerous code\n- The agent API is protected by a randomly-generated `TRINITY_API_KEY`\n- Telegram integration only responds to your specific Chat ID\n- Core skills are read-only inside the container; only `skills/dynamic/` is writable by the agent\n\nHowever, **any modification to the codebase can introduce risk.** This is an inherent property of self-modifying AI agent systems:\n\n- Editing core skills, relaxing the module ban-list, or adding new file-system access can expand the attack surface\n- Prompt injection via untrusted web content or external data sources is a known risk class for all LLM agents\n- Credentials in `.env` (API keys, SMTP passwords, Telegram tokens) should be treated as sensitive — never commit `.env` to a public repository\n- The `code_executor` and `terminal` skills run code inside the container — review any AI-generated code before executing it on sensitive systems\n- Dynamic skills created by the agent should be inspected before being promoted to `skills/core/`\n\nThis project follows responsible AI agent design practices, but **no system is unconditionally safe once modified.** If you extend or customize TrinityClaw, you take on responsibility for auditing those changes.\n\n---\n\n## Features\n\n- **Self-Modifying**: Creates new skills dynamically\n- **Persistent Memory**: ChromaDB vector storage + JSONL logs, daily journaling, goal tracking, and weekly meta-review synthesis across all memory files\n- **Self-Curated Memory Stores**: Agent-remembered facts in two capped file stores — `MEMORY.md` (projects, tools, lessons) and `USER.md` (your preferences and profile) — with size limits, dedup-friendly batch edits, and a context snapshot injected into every new session\n- **Session Memory**: Every new chat starts with a frozen memory snapshot (capped stores, lessons, scheduled tasks, open loops) plus a checkpoint of your last session's state — the agent picks up where you left off without re-reading files\n- **Open Promises Tracking**: A lightweight open-loops list keeps the agent accountable for unfinished promises, follow-ups, and suggestions — surfaced in every session, auto-expired after 14 days, checkable off with a 4-character ID\n- **Ambient Heartbeat**: A background loop that ticks every 15 minutes when your agent is idle — reviews its own memory, follows up on open loops, reads its improvement idea backlog, and pings you on Telegram only when something is worth saying; everything else is silent and logged to an audit file\n- **Multi-Step Reasoning**: Agent loop for complex tasks\n- **Dynamic Skills**: Core system skills + user-created skills\n- **Web Browsing**: Fetch and analyze web content, including JS-rendered pages\n- **Browser Automation**: Full Playwright-powered browser control — navigate, click, type, screenshot, evaluate JS, fill forms\n- **Live Browser Session**: Attach to your existing logged-in Chrome via CDP — post to Twitter/X, LinkedIn, Instagram, and any platform directly from the agent using your real sessions, no API keys required\n- **MCP Client (Model Context Protocol)**: Connect to remote and local MCP servers — discover, test, filter, and call their tools; connected tools become first-class agent skills automatically\n- **Composio Integration**: Connect to 200+ apps (Slack, Notion, Jira, Stripe, HubSpot and more) with OAuth handled automatically\n- **Scheduler**: Run automated tasks\n- **Telegram Integration**: Chat with your agent via text, voice messages, and photos\n- **Google Calendar**: Read, create, update, and delete calendar events — just ask naturally\n- **Gmail Integration**: Read inbox, search emails, download attachments, mark as read — full Gmail API access\n- **Business Knowledge Base**: Drop your documents into a folder and the agent learns from them — meeting notes, SOPs, contracts, spreadsheets\n- **Voice Messages**: Send audio to Telegram or web UI — transcribed locally via Whisper (no API key needed)\n- **Image Vision & OCR**: Send photos via Telegram or web UI — described by a vision-capable LLM; local OCR (Tesseract) extracts text from screenshots, documents, and receipts in English, Italian, Spanish, French, Greek, and Serbian (Cyrillic + Latin)\n- **Secure**: AST validation, skill whitelisting, Docker isolation\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Docker Desktop** (the only prerequisite — it's free): https://www.docker.com/products/docker-desktop/\n  - **Windows:** Docker Desktop requires WSL 2. On Windows 11, WSL is already built in — Docker Desktop's installer enables it automatically. No manual WSL setup needed.\n  - **Mac:** Download the `.dmg`, drag Docker to Applications, open it, and wait for the whale 🐳 icon in your menu bar.\n- 8GB+ RAM recommended\n- 20GB free disk space (50GB+ for local model)\n\n> **No Git required on Windows or Mac.** The installers download the repository automatically.\n>\n> **Browser automation** (Playwright + Chromium, ~300MB) is installed automatically inside the Docker container during build — no extra steps required.\n\n---\n\n### Install — Windows\n\n**Step 1 — Install Docker Desktop**\n\n1. Go to https://www.docker.com/products/docker-desktop/\n2. Click **Download for Windows**\n3. Run the installer (it enables WSL 2 automatically on Windows 11)\n4. Open **Docker Desktop** from the Start menu\n5. Wait for the **whale 🐳 icon** to appear in your taskbar — Docker is ready when you see it\n\n**Step 2 — Run the installer**\n\nPress **Win + R**, paste the command below, and hit **Enter**:\n\n```\npowershell -Command \"irm https://raw.githubusercontent.com/TrinityClaw/trinity-claw/main/install.ps1 | iex\"\n```\n\n> No admin required. No Git required. No file to download.\n\nA terminal window opens and walks you through setup automatically:\n- If Docker isn't running yet, the installer starts it and waits\n- If Docker isn't installed, it opens the download page for you\n- Downloads the full TrinityClaw repo automatically\n- Launches the installer wizard — choose **cloud** or **local** model\n\nAt the end, your **Agent API Key** is printed — copy it and paste it in the Web UI under **Settings ⚙️ → Agent Security**.\n\n> After install, TrinityClaw starts automatically every time Windows boots. A **\"Start TrinityClaw\"** shortcut is placed on your Desktop for manual restarts.\n\n---\n\n### Install — macOS\n\n**Step 1 — Install Docker Desktop**\n\n1. Go to https://www.docker.com/products/docker-desktop/\n2. Click **Download for Mac**\n3. Open the `.dmg` file → drag Docker to Applications\n4. Open **Docker Desktop** from Applications\n5. Wait for the **whale 🐳 icon** in your menu bar — Docker is ready when you see it\n\n**Step 2 — Run the installer**\n\nOpen Terminal (press `⌘ Space`, type `Terminal`, press Enter) and paste:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/TrinityClaw/trinity-claw/main/install.sh | bash\n```\n\nThe installer will:\n- Start Docker Desktop automatically if it's installed but not running\n- Install `docker-compose` via Homebrew if needed (for local model mode)\n- Download the repo if you're running via `curl`\n- Walk you through choosing **cloud** or **local** model\n- Set up a LaunchAgent so TrinityClaw starts automatically on every login\n- Place a **\"Start TrinityClaw.command\"** shortcut on your Desktop\n\nAt the end, copy your **Agent API Key** and enter it in the Web UI under **Settings ⚙️ → Agent Security**.\n\n> **Already have the repo cloned?** `cd` into it and run `bash install.sh` instead.\n\n---\n\n### Install — Linux\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/TrinityClaw/trinity-claw/main/install.sh | bash\n```\n\nDocker Engine is installed automatically if not present. That's it.\n\n---\n\nDuring installation you will be asked to choose:\n- **Cloud** — use a remote provider (OpenAI, NVIDIA, Anthropic, etc.) — requires API key\n- **Local** — use Ollama with `qwen3.5:9b` running on your machine — no API key needed (~6.6 GB download) if you have 16GB or more VRAM recomendation is to go with qwen3.8 27b quantized to 12gb\n\nAfter installation, open the Web UI at: **http://localhost:8080**\n\n---\n\n## Configuration\n\n### LLM Setup\n\nChoose your model source during installation:\n\n#### Option A — Cloud Provider (requires API key)\n\n| Parameter | Description | Example |\n|-----------|-------------|---------|\n| Model Name | LLM model identifier | `openai/moonshotai/kimi-k2-instruct` |\n| API Base URL | Provider API endpoint | `https://integrate.api.nvidia.com/v1` |\n| API Key Name | Environment variable name | `NVIDIA_API_KEY` |\n| API Key Value | Your actual API key | `nvapi-xxxxx` |\n\n#### Option B — Local Model via Ollama (no API key needed)\n\n- Model: `qwen3.5:9b` (~6.6GB download on first start)\n- Requires: 8GB+ VRAM (GPU) or 16GB+ RAM (CPU-only, slower)\n- On **Linux**: pulled automatically by `ollama-entrypoint.sh` inside Docker on first startup\n- On **Mac**: pulled during `install.sh` via native Ollama (Homebrew)\n- Start command: `docker compose --profile local up -d` (Linux) / `docker compose -f docker-compose.mac.yml up -d` (Mac)\n- **Mac auto-start**: after running `install.sh`, TrinityClaw starts automatically on every login — no terminal needed. A `Start TrinityClaw.command` shortcut is placed on your Desktop as a manual backup.\n\n```bash\n# Linux — start with local Ollama model\ndocker compose --profile local up -d\n\n# Monitor model download progress (Linux)\ndocker logs trinity-claw-ollama-1 -f\n\n# If the model was not pulled automatically, pull it manually:\n\n# Mac (native Ollama)\nollama pull qwen3.5:9b\n\n# Linux (inside Docker container)\ndocker exec trinity-claw-ollama-1 ollama pull qwen3.5:9b\n```\n\n### Supported Providers\n\n| Provider | Model Example | API Base |\n|----------|---------------|----------|\n| NVIDIA | `openai/moonshotai/kimi-k2-instruct` | `https://integrate.api.nvidia.com/v1` |\n| OpenAI | `openai/gpt-4o` | `https://api.openai.com/v1` |\n| Anthropic | `anthropic/claude-3-5-sonnet-20241022` | `https://api.anthropic.com/v1` |\n| Moonshot | `openai/moonshot-v1-8k` | `https://api.moonshot.cn/v1` |\n| Local (Ollama) | `ollama/qwen3.5:9b` | `http://localhost:11434` |\n\n### Configuration Files\n\n```\ntrinity-claw/\n├── .env                        # Secrets (API keys)\n├── identity.md                 # Agent personality, values, and standing orders (editable)\n└── config/\n    └── litellm_config.yaml     # Model configuration\n```\n\n**identity.md** defines who TrinityClaw is — its values, communication style, and standing orders. Edit this file to customize the agent's personality without touching any Python code. Changes take effect on the next chat request (no restart needed).\n\n**.env example:**\n```env\nNVIDIA_API_KEY=nvapi-xxxxx\nLITELLM_MASTER_KEY=sk-trinity-local-key\nTRINITY_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   # auto-generated by installer\nTAVILY_API_KEY=tvly-xxxxx                            # optional — get free key at tavily.com\n```\n\n**litellm_config.yaml example:**\n```yaml\nmodel_list:\n  - model_name: trinity-default\n    litellm_params:\n      model: openai/moonshotai/kimi-k2-instruct\n      api_key: os.environ/NVIDIA_API_KEY\n      api_base: https://integrate.api.nvidia.com/v1\n\n  # Vision model — used automatically when photos are sent.\n  # If your main model supports vision (gpt-4o, claude-3-5-sonnet) set both to the same model.\n  # For NVIDIA text-only models, use a dedicated vision model:\n  - model_name: trinity-vision\n    litellm_params:\n      model: openai/meta/llama-3.2-90b-vision-instruct\n      api_key: os.environ/NVIDIA_API_KEY\n      api_base: https://integrate.api.nvidia.com/v1\n\ngeneral_settings:\n  master_key: os.environ/LITELLM_MASTER_KEY\n```\n\n### Agent Security (API Key)\n\nDuring installation, a **random `TRINITY_API_KEY` is automatically generated** and written to `.env`.\nIt is printed at the end of the installer — copy it and enter it **once** in the Web UI.\n\n**How it works:**\n\n| Step | Where | Action |\n|------|-------|--------|\n| Install | Installer | Generates random key → saves to `.env` |\n| First use | Browser → Settings ⚙️ → Agent Security | Paste your key |\n| Every use after | Browser `localStorage` | Sent automatically, nothing to do |\n| Key changes? | Only if you re-run the installer | Enter new key in Settings once |\n\n**What it protects:**\n- `POST /config/update` — changing your LLM model/provider\n- `POST /config/update-api-key` — writing API keys to `.env`\n- `POST /config/telegram/update` — Telegram bot credentials\n- `POST /config/model-source/set` — switching local/cloud\n\n> **Note:** If `TRINITY_API_KEY` is not set in `.env`, the check is silently skipped (backward compatible). Read-only endpoints like `/health`, `/skills`, `/chat` are not protected by this key.\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    TRINITYCLAW ARCHITECTURE                  │\n├─────────────────────────────────────────────────────────────┤\n│                                                             │\n│   ┌─────────────────────────────────────────────────────┐  │\n│   │                    app.py                            │  │\n│   │         (Nervous System - Coordination)              │  │\n│   │  ┌──────────┐ ┌──────────┐ ┌──────────┐            │  │\n│   │  │Chat API  │ │  Skills  │ │  Memory  │            │  │\n│   │  │          │ │ Registry │ │ Manager  │            │  │\n│   │  └──────────┘ └────┬─────┘ └──────────┘            │  │\n│   └────────────────────┼────────────────────────────────┘  │\n│                        │                                   │\n│              ┌─────────┴─────────┐                        │\n│              ▼                   ▼                        │\n│   ┌─────────────────┐  ┌─────────────────┐               │\n│   │  skills/core/   │  │ skills/dynamic/ │               │\n│   │  (Read-only)    │  │  (Read-write)   │               │\n│   │  - notes        │  │  - (AI creates) │               │\n│   │  - files        │  │                 │               │\n│   │  - web          │  │                 │               │\n│   │  - code_executor│  │                 │               │\n│   │  - create_skill │  │                 │               │\n│   │  - git_manager  │  │                 │               │\n│   │  - scheduler    │  │                 │               │\n│   │  - telegram_bot │  │                 │               │\n│   │  - meta_review  │  │                 │               │\n│   └─────────────────┘  └─────────────────┘               │\n│                                                             │\n│   ┌─────────────────────────────────────────────────────┐  │\n│   │    LiteLLM ◄────────► External LLM Provider         │  │\n│   └─────────────────────────────────────────────────────┘  │\n│                                                             │\n│   ┌─────────────────────────────────────────────────────┐  │\n│   │    ChromaDB + JSONL ◄─── Persistent Memory          │  │\n│   └─────────────────────────────────────────────────────┘  │\n│                                                             │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Memory & Autonomy\n\nTrinityClaw's memory went through a rework to feel less like a chatbot and more like a colleague who actually remembers things. The stack has three layers:\n\n### 1. Self-Curated Memory Stores\n\nInstead of only scrolling logs, the agent maintains two hand-edited, size-capped markdown stores:\n\n| Store | Purpose | Cap (chars) |\n|-------|---------|-------------|\n| `memory/MEMORY.md` | Environment facts, project conventions, tool quirks, hard-won lessons | 2200 (`MEMORY_CORE_LIMIT`) |\n| `memory/USER.md` | Your preferences, communication style, recurring patterns | 1375 (`MEMORY_USER_LIMIT`) |\n\nWrites fail **with an overflow error and the exact shortfall** when a store is full — the agent is instructed to consolidate (merge/dedup stale entries) in the same batch rather than dropping information. The `memory.batch()` function applies add/patch/remove ops atomically, checking the cap only on the final result, so free-then-add works in one call.\n\n### 2. Session Snapshot & Checkpoints\n\nEvery new chat session gets a `<MEMORY_SNAPSHOT>` block injected once at startup (frozen for the session — mid-session writes surface next time):\n\n- Both capped stores, top-3 learned lessons, active scheduler tasks, and skill-health\n- The **open loops list** (see below)\n- A **session checkpoint** (`memory/session_checkpoints.json`, last 10 kept) so the agent resumes where your previous conversation left off\n- Cross-session recall (`memory/lessons.jsonl` archive + FTSS/ChromaDB via `memory_search`) for anything older — including daily-journal lookup, which lives at `memory/daily_journal.jsonl`\n\n### 3. Open Loops (unfinished promises)\n\nThe agent keeps a lightweight TODO-of-integrity at `memory/open_loops.json`: anything it promised to do, suggested, or said it would follow up on. Every session it sees the list and is expected to close what's closable (`open_loops__done` with a 4-character ID) before opening fresh loops. Entries auto-expire after 14 days, and the list is capped at 20.\n\n```text\n<OPEN_LOOPS>\n- a1b2c3: research Ollama vision models for you (opened 2026-10-15)\n- d4e5f6: promised to check CI logs after the next push (opened 2026-10-18)\n</OPEN_LOOPS>\n```\n\n### Ambient Heartbeat\n\nWhen you're not around, the agent doesn't just idle. A daemon thread ticks every **15 minutes** and, if you've been quiet for at least 2 minutes and no conversation turn is running, a **local-model LLM call** asks one question over a compact context (open loops, due scheduler tasks, latest journal line, the improvement-idea backlog, quiet duration):\n\n> *Is there anything worth doing or saying right now?*\n\nIt answers with one of four verdicts:\n\n| Verdict | Behavior |\n|---------|----------|\n| `NO_REPLY` | **Everything stays silent** — no message, no chat history entry; just one audit row |\n| Statement / observation | Also silent — logged to the audit file for later reading |\n| `PING: <text>` | Sends a single Telegram message (≤500 chars) and pings you |\n| Tool calls + `ACT DONE:` | Acts (≤3 rounds, ≤5 tool actions), then logs what it did |\n\n**Safety rails:**\n\n- A mechanical **deny-list** hard-blocks dangerous skills during ticks: `terminal`, browser/X engagement actions, `web_builder`, `knowledge_base` ingestion, git push/commit, and all `autoimprove` mutation loops\n- Escalation to the cloud LLM happens **only after two failed local attempts** and is capped at **1 escalation per hour** — a silent-hours cloud-bill guard when running against a paid provider\n- Every tick leaves exactly one JSON line in `memory/heartbeat.jsonl` (verdict, summary, token usage) — the audit file is the only observability surface\n\n**Environment variables** (all optional, sensible defaults):\n\n```env\nHEARTBEAT_ENABLED=true            # master switch (set false to disable)\nHEARTBEAT_INTERVAL_SECONDS=900    # tick cadence (floored at 60)\nHEARTBEAT_MAX_CLOUD=1             # max cloud escalations per rolling hour (0 = local-only)\n```\n\n---\n\n## Core Skills (37)\n\n| Skill | Description | Functions |\n|-------|-------------|-----------|\n| `memory` | Agent-curated persistent memory — two capped stores: `MEMORY.md` (agent/project facts) and `USER.md` (user profile); writes persist immediately and surface in the next session's snapshot | `add`, `patch`, `remove`, `batch`, `consolidate` |\n| `memory_search` | Recall past context on demand — keyword search over conversation history (FTS5) and semantic search over lessons/memory (ChromaDB) | `session_search`, `semantic_search`, `prune_memory_db` |\n| `open_loops` | Track unfinished promises, follow-ups, and suggestions; rendered into every session snapshot; loops auto-expire after 14 days | `add`, `done`, `list` |\n| `heartbeat` | Ambient autonomy daemon (no callable functions) — a background thread ticks every 15 minutes when the agent is idle: reviews memory, tracks down open loops, works through its improvement-idea backlog, and messages you on Telegram only when something is worth saying (see Ambient Heartbeat section) | *(background thread — silent unless it has something to report)* |\n| `notes` | Persistent notes, daily journal, user model, and goal tracking | `save`, `load`, `list_notes`, `delete`, `search`, `export_all`, `get_last_logs`, `search_logs`, `end_day`, `daily_review`, `get_activity_log`, `set_preference`, `get_preference`, `record_pattern`, `set_context`, `update_user_model`, `get_user_model`, `prune_user_model`, `set_user_fact`, `get_user_facts_card`, `add_goal`, `complete_goal`, `list_goals` |\n| `meta_review` | Weekly synthesis of all memory files into actionable insights | `weekly_digest`, `loop_roi_report`, `error_trend_report` |\n| `files` | File operations (read anywhere, write to memory/dynamic) | `ls`, `cat`, `pwd`, `exists`, `size`, `sha256`, `write`, `append`, `patch`, `patch_all`, `mkdir`, `delete`, `tree`, `find_duplicates` |\n| `web` | Web browsing + browser automation. `search()` auto-tries Tavily → DuckDuckGo → Bing (set `TAVILY_API_KEY` for best results) | `fetch`, `get`, `head`, `read`, `search`, `download`, `scrape`, `scrape_links`, `scrape_images`, `scrape_table`, `extract_meta`, `browser_goto`, `browser_click`, `browser_type`, `browser_screenshot`, `browser_text`, `browser_fill`, `browser_evaluate`, `browser_wait`, `browser_links`, `browser_inputs`, `browser_scroll`, `browser_press`, `browser_close`, `status` |\n| `code_executor` | Safe Python sandbox + math evaluator | `run_snippet`, `test_skill`, `run_bash`, `calc`, `status` |\n| `create_skill` | Create new skills dynamically | `create_new_skill`, `reload` |\n| `scheduler` | Schedule one-time and recurring tasks | `schedule`, `schedule_recurring`, `remove`, `list_tasks`, `clear`, `status`, `parse_preview` |\n| `git_manager` | Git repository management (read + write) | `status`, `is_repo`, `list_repos`, `branches`, `head`, `diff`, `log`, `add`, `commit`, `pull`, `push` |\n| `document_parser` | Parse PDF, DOCX, XLSX, CSV, TXT, JSON, YAML | `read`, `extract_tables`, `metadata`, `summarize`, `convert_to_text`, `list_supported` |\n| `data_science` | EDA, ML prediction, NLP, charts | `analyze_dataset`, `predict_column`, `analyze_text_column`, `create_chart`, `status` |\n| `image_viewer` | View and inspect local images | `view_image`, `list_images`, `inspect_image` |\n| `url_monitor` | Monitor URLs for changes and health | `add_url`, `get_status_summary`, `get_url_history`, `get_recent_changes`, `check_all_urls`, `check_url_now`, `remove_url` |\n| `self_improvement` | Audit, auto-fix, and learn from skill errors | `audit`, `fix`, `prevent`, `report`, `suggest_tests`, `learn_from_feedback` |\n| `dashboard` | System health and monitoring | `health`, `alerts`, `processes` |\n| `terminal` | Whitelisted shell commands inside container | `run` |\n| `google_calendar` | Google Calendar read/write | `authorize`, `list_events`, `create_event`, `delete_event`, `update_event`, `find_free_slots`, `status` |\n| `telegram_bot` | Telegram messaging and polling | `setup`, `send`, `queue_message`, `send_photo`, `send_document`, `start_polling`, `stop`, `status`, `test_connection` |\n| `email_sender` | Email via SMTP or SendGrid | `send`, `send_html`, `send_with_attachment`, `test`, `status` |\n| `web_builder` | Build & preview HTML/CSS/JS websites | `scaffold`, `write_file`, `patch_file`, `read_file`, `delete_file`, `delete_project`, `export_zip`, `list_projects`, `serve`, `stop_server`, `server_status`, `validate` |\n| `knowledge_base` | Business knowledge base backed by ChromaDB | `ingest_folder`, `ingest_file`, `search`, `list_ingested`, `delete_document`, `status` |\n| `gmail_reader` | Read Gmail inbox via Gmail API | `authorize`, `list_inbox`, `read_email`, `search_emails`, `get_attachments`, `mark_read`, `summarize_inbox`, `status` |\n| `competitive_intel` | Monitor competitor websites for pricing, messaging, and content changes. Snapshots stored with deduplication and noise filtering. High-priority changes send Telegram alerts automatically. | `add_site`, `remove_site`, `list_watchlist`, `check_site`, `run_check`, `get_alerts`, `clear_alerts`, `schedule_daily` |\n| `google_drive` | Google Drive file management — list, search, upload, download, create folders, delete. Uses same `gcal_credentials.json` as Calendar. | `authorize`, `list_files`, `search_files`, `get_file_info`, `create_folder`, `upload_file`, `upload_to_folder`, `download_file`, `delete_file`, `status` |\n| `meeting_notes` | Extract structured information from meeting transcripts or documents (PDF, DOCX, TXT, MD, or raw text). Uses LLM to produce summary, decisions, action items, attendees, and topics. | `extract`, `save_meeting` |\n| `youtube` | YouTube Data API — search videos and channels with view/subscriber metrics. Supports both OAuth and simple API key auth. | `authorize`, `activate`, `status`, `search_videos`, `search_channels` |\n| `autoimprove` | Autonomous self-improvement loops — web research, propose/apply/test cycles for dynamic skills, and queued patch suggestions for core skills | `research`, `run_experiment`, `run_loop`, `run_all`, `suggest_core`, `list_suggestions`, `apply_suggestion`, `schedule_nightly`, `report`, `status` |\n| `browser_session` | Attach to your existing logged-in Chrome via CDP — sees all sessions, cookies, and open tabs. Includes stealth headless sessions and built-in Twitter/X, TikTok, Gmail shortcuts. One-time setup: launch Chrome with `--remote-debugging-port=9222`. | `list_tabs`, `goto`, `get_snapshot`, `click_ref`, `fill_ref`, `click_accessible`, `type_accessible`, `scroll`, `press_key`, `wait_for`, `new_tab`, `close_tab`, `tweet`, `like_tweet`, `reply_tweet`, `follow_user`, `tiktok_like`, `tiktok_comment`, `tiktok_follow`, `send_gmail`, `stealth_start`, `stealth_goto`, `stealth_snapshot`, `stealth_click_ref`, `stealth_fill_ref`, `stealth_screenshot`, `stealth_scroll`, `stealth_press`, `stealth_save`, `stealth_close` |\n| `database` | SQLite structured data storage. Databases live in `/app/memory/databases/`. Parameterized queries — no SQL injection risk. | `create_table`, `drop_table`, `insert`, `upsert`, `update`, `delete_rows`, `select`, `count`, `list_databases`, `list_tables`, `describe`, `export_csv` |\n| `google_maps` | Maps & location — geocoding, directions, place search. No API key required (uses OpenStreetMap/Nominatim + OSRM). | `map_url`, `geocode`, `reverse_geocode`, `search_places`, `nearby_search`, `get_directions`, `distance_matrix`, `status` |\n| `weather_api` | Real-time weather, multi-day forecast (up to 16 days), and air quality. No API key required. | `get_weather`, `get_forecast`, `get_air_quality` |\n| `website_cloner` | Scrape a live website's design tokens (CSS variables, colors, fonts, section structure) and scaffold a `web_builder` project from them. | `extract_tokens`, `clone` |\n| `mcp_client` | Connect to MCP servers (Streamable HTTP, legacy HTTP+SSE, stdio), discover/test/filter tools — connected tools become first-class agent skills (see MCP Client section) | `connect_server`, `list_servers`, `ping_server`, `test_server`, `list_tools`, `list_all_mcp_tools`, `enable_tool`, `disable_tool`, `set_server_enabled`, `call_tool`, `remove_server`, `discover_workspace_servers`, `list_resources`, `read_resource`, `list_prompts`, `get_prompt` |\n| `composio` | Connect to 200+ external apps (Slack, Notion, Jira, Stripe, etc.) via Composio — OAuth handled automatically (see Composio section) | `status`, `list_apps`, `search_tools`, `list_tools`, `execute_tool`, `list_connected_accounts`, `get_auth_url`, `check_connection` |\n\n---\n\n## Live Browser Session\n\nThe `browser_session` dynamic skill lets the agent attach to your **existing logged-in Chrome** via Chrome DevTools Protocol (CDP). Unlike the `web` skill which launches a fresh private browser with no sessions, `browser_session` sees everything you're logged into — Twitter/X, LinkedIn, Instagram, WordPress, and any other platform — and can interact with it exactly like a human would.\n\n### One-Time Setup\n\n**1. Create a Chrome shortcut.** Right-click Desktop → New → Shortcut → paste this as the target, name it `ChromeTrinity`:\n\n```\n\"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe\" --remote-debugging-port=9222 --user-data-dir=\"C:\\ChromeDebug\"\n```\n\n`--user-data-dir` is required — it forces Chrome to start as a fully independent process. Without it, Chrome hands off to any existing instance and the debug flag is ignored.\n\n> Before launching: close all Chrome windows and kill any `chrome.exe` in Task Manager → Details tab.\n\n**2. Create the port proxy** — run this once in CMD **as Administrator** (survives reboots):\n\n```\nnetsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=9223 connectaddress=127.0.0.1 connectport=9222\n```\n\nChrome on Windows only binds its debug port to `127.0.0.1` (loopback). Docker containers can't reach loopback directly, so this proxy bridges port 9223 on all interfaces to Chrome's port 9222. Verify:\n\n```\nnetstat -an | findstr 9223\n```\n\nYou should see `TCP 0.0.0.0:9223 LISTENING`. This rule persists across reboots — you only need to run it once.\n\n**3. Launch ChromeTrinity** and verify Chrome is listening:\n\n```\nnetstat -an | findstr 9222\n```\n\nYou should see `TCP 127.0.0.1:9222 LISTENING`.\n\n**4. Log in once** to Twitter, LinkedIn, Instagram, etc. in this ChromeDebug profile. Sessions are saved in `C:\\ChromeDebug` and persist forever.\n\n> Your normal Chrome and ChromeTrinity run simultaneously with no conflicts.\n\n> **Linux users:** The portproxy is Windows-only. On Linux, launch Chrome with `--remote-debugging-address=0.0.0.0` (Linux Chrome honours this flag) and set `BROWSER_CDP_URL=http://172.17.0.1:9222` in `.env`.\n\n### Available Functions\n\n| Function | Description |\n|----------|-------------|\n| `list_tabs()` | List all open tabs with index, title, and URL |\n| `screenshot(tab_index?)` | Capture current tab — saved to `/app/memory/browser_screenshots/` |\n| `goto(url, tab_index?)` | Navigate to a URL |\n| `get_text(tab_index?)` | Extract visible page text (up to 5000 chars) |\n| `get_html(tab_index?, selector?)` | Get full HTML or a specific element's HTML |\n| `click(target, tab_index?)` | Click by CSS selector, `text=Foo`, or `[aria-label=\"Bar\"]` |\n| `type_text(target, text, clear_first?, tab_index?)` | Type into any field — works on `<input>` and `contenteditable` divs (Twitter, LinkedIn) |\n| `scroll(direction, tab_index?)` | Scroll: `up` / `down` / `top` / `bottom` |\n| `press_key(key, tab_index?)` | Press keyboard key: `Enter`, `Escape`, `Control+Enter`, etc. |\n| `wait_for(selector, tab_index?, timeout_ms?)` | Wait for an element before the next action |\n| `new_tab(url?)` | Open a new tab, optionally navigate to URL |\n| `evaluate(js_code, tab_index?)` | Run JavaScript and return the result |\n\n### Example — Posting a Tweet\n\n```\nbrowser_session.screenshot()\nbrowser_session.goto(\"https://x.com\")\nbrowser_session.click('[data-testid=\"SideNav_NewTweet_Button\"]')\nbrowser_session.type_text('[data-testid=\"tweetTextarea_0\"]', \"Your content here\")\nbrowser_session.screenshot()   ← verify before posting\nbrowser_session.click('[data-testid=\"tweetButtonInline\"]')\n```\n\n### What This Replaces\n\nInstead of building separate Twitter API, LinkedIn API, and Instagram API integrations — each requiring OAuth app approval, developer accounts, and rate limits — the agent uses your real browser session on every platform simultaneously. Any site you can use in a browser, the agent can use too.\n\n---\n\n## MCP Client (Model Context Protocol)\n\nTrinityClaw includes a built-in MCP client (`agent/skills/core/mcp_client.py`) that connects it to remote and local MCP servers. Register a server once and its tools become **first-class agent skills** — the model calls them directly during normal chat, no extra setup.\n\n### Supported Transports\n\n| Transport | Use for | Config |\n|-----------|---------|--------|\n| **Streamable HTTP** (default) | Modern remote MCP servers | `{\"url\": \"https://example.com/mcp\"}` |\n| **HTTP+SSE** (legacy) | Older remote servers | `{\"transport\": \"sse\", \"url\": \"https://example.com/sse\"}` |\n| **stdio** | Local subprocess servers | `{\"transport\": \"stdio\", \"command\": \"npx\", \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\"]}` |\n\n### Connecting a Server\n\n**Easiest — just ask the agent** (Web UI at http://localhost:8080, or Telegram):\n\n> \"Connect to the Context7 MCP server at https://mcp.context7.com/mcp\"\n\n**Or via the API:**\n\n```bash\ncurl -X POST http://localhost:8001/skill/call \\\n  -H \"Authorization: Bearer $TRINITY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"skill\": \"mcp_client\", \"function\": \"connect_server\", \"args\": [\"ctx\", \"https://mcp.context7.com/mcp\"]}'\n```\n\n**With authentication** — pass `auth_token` and it is saved to `.env` as `MCP_<NAME>_TOKEN` automatically (the registry references it by env-var name, never in plain config):\n\n```bash\ncurl -X POST http://localhost:8001/skill/call \\\n  -H \"Authorization: Bearer $TRINITY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"skill\": \"mcp_client\", \"function\": \"connect_server\", \"args\": [\"github\", \"https://api.githubcopilot.com/mcp\"], \"kwargs\": {\"auth_token\": \"ghp_xxx\"}}'\n```\n\n**Local stdio servers** (subprocess inside the agent container):\n\n```bash\ncurl -X POST http://localhost:8001/skill/call \\\n  -H \"Authorization: Bearer $TRINITY_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"skill\": \"mcp_client\", \"function\": \"connect_server\", \"args\": [\"fs\"], \"kwargs\": {\"config\": {\"transport\": \"stdio\", \"command\": \"npx\", \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\"]}}}'\n```\n\n### Managing Servers\n\n| Function | What it does |\n|----------|-------------|\n| `list_servers()` | Registered servers, auth state, tool counts |\n| `list_tools(name)` / `list_all_mcp_tools()` | Discover tools (per server / across all enabled servers) |\n| `ping_server(name)` / `test_server(name)` | Health check with latency + auth diagnostics |\n| `enable_tool(server, tool)` / `disable_tool(server, tool)` | Allow/deny a specific tool |\n| `set_server_enabled(name, true/false)` | Enable/disable an entire server |\n| `remove_server(name)` | Unregister and remove its token from `.env` |\n| `discover_workspace_servers()` | Detect `.trinity/mcp.json`, `.mcp.json`, `.vscode/mcp.json` — dry-run by default; `register=True, trust=True` registers servers as **disabled** |\n| `list_resources(name)` / `read_resource(name, uri)` | Browse and read server resources |\n| `list_prompts(name)` / `get_prompt(name, prompt)` | Browse and render server prompts |\n\n### Calling Tools\n\nOnce connected, tools are exposed to the model as `mcp_<server>_<tool>` and are called automatically during normal conversation (\"create an issue in my repo\"). You can also call them directly:\n\n```\n<skill:mcp_client.call_tool>github,create_issue,{\"repo\":\"owner/repo\",\"title\":\"Bug report\"}</skill:mcp_client.call_tool>\n```\n\n### Security\n\n- Auth tokens live in `.env`, referenced by env-var name — never hardcoded in `mcp_servers.json`\n- MCP tool output is treated as untrusted external content and sanitized before reaching the model\n- stdio servers receive a minimal environment — your `.env` secrets are withheld unless explicitly configured via `${VAR}` references\n- Workspace-discovered stdio servers are registered **disabled** by default\n- Registry file: `memory/mcp_servers.json` (inside the container: `/app/memory/mcp_servers.json`)\n\n---\n\n## Composio Integration (200+ Apps)\n\nTrinityClaw includes a built-in Composio skill (`agent/skills/core/composio.py`) that connects to 200+ external apps — Slack, Notion, Jira, Stripe, HubSpot, Linear, Airtable, and more — without writing a custom skill per service. Composio handles OAuth flows and token refreshes automatically.\n\n### Setup (one-time, ~2 minutes)\n\n**Easiest — just ask the agent** (Web UI at <http://localhost:8080>, or Telegram):\n\n> \"Set up composio\"\n\nThe agent will open composio.dev in your browser, walk you through each step, and save your key automatically once you paste it.\n\n**Or manually:**\n\n1. **Create a free account** at [composio.dev](https://composio.dev)\n2. **Copy your API key** from the Composio dashboard\n3. **Add it to your `.env`:**\n\n```\nCOMPOSIO_API_KEY=your_api_key_here\n```\n\n4. **Install the SDK** (if not already installed). TrinityClaw runs in Docker, so add `composio` to `agent/requirements.txt` and rebuild:\n\n```\ndocker-compose down\ndocker-compose build --no-cache trinity-agent\ndocker-compose up -d\n```\n\n5. **Verify:**\n\n```\n> \"check composio status\"\n```\n\n### Available Functions\n\n| Function | What it does |\n| --- | --- |\n| `setup(api_key?)` | Guided setup wizard — opens browser, saves key, installs SDK |\n| `status()` | Check API key, SDK installed, connection state |\n| `list_apps()` | List all 200+ available apps |\n| `search_tools(query)` | Search tools by name or description |\n| `list_tools(app?)` | List tools for a specific app |\n| `execute_tool(name, params)` | Run a tool with JSON parameters |\n| `list_connected_accounts()` | Show all OAuth-connected apps |\n| `get_auth_url(app)` | Start an OAuth flow for an app |\n| `check_connection(app)` | Verify an app is connected |\n\n### Example — Send a Slack Message\n\n```\n# 1. Connect Slack (opens OAuth URL in browser)\n> \"get auth url for slack\"\n\n# 2. Verify connection\n> \"check connection slack\"\n\n# 3. Find the right tool\n> \"search composio tools for slack send message\"\n\n# 4. Execute it\n> \"execute tool SLACK_SEND_MESSAGE with {\"channel\":\"#general\",\"text\":\"Hello from Trinity!\"}\"\n```\n\n### Security\n\n- `COMPOSIO_API_KEY` is read from `.env` — never printed or returned in results\n- Tool output is treated as untrusted external content and sanitized before reaching the model (same pipeline as MCP client output)\n- Only the minimum scopes configured at composio.dev are granted — this skill cannot escalate scopes\n- OAuth tokens are managed by Composio's SDK, not stored in TrinityClaw's memory\n\n---\n\n## Skill Invocation\n\nTrinityClaw uses XML-style skill tags:\n\n```\n<skill:skillname.function>arg1,arg2</skill:skillname.function>\n```\n\n### Examples\n\n```\n# List files\n<skill:files.ls>/app/memory</skill:files.ls>\n\n# Save a note\n<skill:notes.save>MyNote,This is important information</skill:notes.save>\n\n# Read a note\n<skill:notes.load>MyNote</skill:notes.load>\n\n# Create a skill\n<skill:create_skill.create_new_skill>greeter,def greet(name): return f\"Hello {name}!\"</skill:create_skill.create_new_skill>\n\n# Quick math (no subprocess)\n<skill:code_executor.calc>sqrt(144) + 2**8</skill:code_executor.calc>\n\n# Run a Python snippet\n<skill:code_executor.run_snippet>print(sum(range(100)))</skill:code_executor.run_snippet>\n\n# Git: check status\n<skill:git_manager.status>/app/myrepo</skill:git_manager.status>\n\n# Git: show last 5 commits\n<skill:git_manager.log>/app/myrepo,5</skill:git_manager.log>\n\n# Git: stage all and commit\n<skill:git_manager.add>/app/myrepo,.</skill:git_manager.add>\n<skill:git_manager.commit>/app/myrepo,Fix bug in parser</skill:git_manager.commit>\n\n# Git: pull latest\n<skill:git_manager.pull>/app/myrepo</skill:git_manager.pull>\n\n# Fetch webpage (static)\n<skill:web.fetch>https://example.com</skill:web.fetch>\n\n# Navigate browser to a JS-rendered page\n<skill:web.browser_goto>https://example.com</skill:web.browser_goto>\n\n# Take a screenshot\n<skill:web.browser_screenshot>/app/memory/shot.png,true</skill:web.browser_screenshot>\n\n# Extract visible text (after JS execution)\n<skill:web.browser_text></skill:web.browser_text>\n\n# Click a button\n<skill:web.browser_click>#submit-btn</skill:web.browser_click>\n\n# Type into a search field\n<skill:web.browser_type>input[name=q],hello world</skill:web.browser_type>\n\n# Run JavaScript on the page\n<skill:web.browser_evaluate>document.title</skill:web.browser_evaluate>\n\n# Close browser when done\n<skill:web.browser_close></skill:web.browser_close>\n\n# Schedule a one-time task\n<skill:scheduler.schedule>morning_check,tomorrow at 9am,check the news</skill:scheduler.schedule>\n\n# Schedule a recurring task\n<skill:scheduler.schedule_recurring>daily_report,24h,summarize today's notes</skill:scheduler.schedule_recurring>\n\n# Create a landing page project\n<skill:web_builder.scaffold>my-portfolio,landing</skill:web_builder.scaffold>\n\n# Write/update a file in the project\n<skill:web_builder.write_file>my-portfolio,style.css,body { background: #1a1a2e; color: #eee; }</skill:web_builder.write_file>\n\n# Start the live preview server (open http://localhost:8090)\n<skill:web_builder.serve>my-portfolio</skill:web_builder.serve>\n\n# Validate index.html structure\n<skill:web_builder.validate>my-portfolio</skill:web_builder.validate>\n\n# List all projects\n<skill:web_builder.list_projects></skill:web_builder.list_projects>\n\n# Stop the preview server\n<skill:web_builder.stop_server></skill:web_builder.stop_server>\n\n# Google Calendar — list next 7 days\n<skill:google_calendar.list_events>7</skill:google_calendar.list_events>\n\n# Google Calendar — create an event\n<skill:google_calendar.create_event>Team Meeting,2026-03-01,09:00,60,Weekly sync</skill:google_calendar.create_event>\n\n# Google Calendar — find free slots\n<skill:google_calendar.find_free_slots>tomorrow,30</skill:google_calendar.find_free_slots>\n\n# Google Calendar — update event title\n<skill:google_calendar.update_event>EVENT_ID,title,New Title</skill:google_calendar.update_event>\n\n# Google Calendar — delete an event\n<skill:google_calendar.delete_event>EVENT_ID</skill:google_calendar.delete_event>\n```\n\n---\n\n## Creating Custom Skills\n\n### Skill Lifecycle\n\n1. **Agent creates skill** — saved to `skills/dynamic/` and immediately usable\n2. **You inspect** the generated file at `agent/skills/dynamic/your_skill.py`\n3. **You move it** to `agent/skills/core/your_skill.py` once satisfied (optional — for permanent core status)\n4. **You tell the agent** `\"activate your_skill\"` — the agent calls `create_skill.reload` which reloads all skills from both folders\n\n> Skills in `dynamic/` are callable right after creation. Moving to `core/` just makes them part of the read-only system layer that persists across container rebuilds.\n\n### Skill Template\n\n```python\n# skills/dynamic/my_skill.py\n\nNAME = \"my_skill\"\nDOC = \"Description of what this skill does\"\n\ndef my_function(arg1: str, arg2: str = \"default\") -> str:\n    \"\"\"\n    Function description.\n    \n    Args:\n        arg1: First argument\n        arg2: Second argument (optional)\n    \n    Returns:\n        Result string\n    \"\"\"\n    result = f\"Processed {arg1} with {arg2}\"\n    return result\n\n# Add more functions as needed\ndef another_function():\n    return \"Another result\"\n```\n\n### Security Restrictions\n\n**Banned modules:**\n- `shutil`, `threading`, `multiprocessing`\n- `subprocess`, `socket`, `ctypes`\n- Any module with system-level access\n\n**Banned functions:**\n- `eval()`, `exec()`, `compile()`\n- `fork()`, `spawn()`\n\n### Skill Best Practices\n\n1. **Return strings** - All functions should return str\n2. **Handle errors** - Use try/except blocks\n3. **Keep it simple** - One skill = one purpose\n4. **Document** - Use clear function docstrings\n5. **Validate input** - Check arguments before processing\n\n---\n\n## Telegram Integration\n\n### Setup\n\n1. **Create Telegram Bot:**\n   - Open Telegram, search `@BotFather`\n   - Send `/newbot`, follow instructions\n   - Copy the bot token\n\n2. **Get Your Chat ID:**\n   - Search `@userinfobot` on Telegram\n   - Send any message\n   - Copy your Chat ID number\n\n3. **Configure TrinityClaw:**\n```\n<skill:telegram_bot.setup>YOUR_BOT_TOKEN,YOUR_CHAT_ID</skill:telegram_bot.setup>\n<skill:telegram_bot.start_polling></skill:telegram_bot.start_polling>\n```\n\n4. **Test:** Message your bot on Telegram!\n\n### Supported Message Types\n\n| Type | Telegram | Web UI |\n|------|----------|--------|\n| Text | ✅ | ✅ |\n| Voice / audio | ✅ Transcribed by local Whisper | ✅ Record with 🎤 button |\n| Photos / images | ✅ Described by vision model | ✅ Attach with 📎 button |\n\n> **Voice transcription** uses [faster-whisper](https://github.com/SYSTRAN/faster-whisper) running locally inside Docker — no API key required. The model (~150 MB) downloads automatically on the first voice message and is cached in the `memory/` volume.\n\n> **Image vision** requires a vision-capable model in `trinity-vision` (see Configuration above). For local Ollama mode, `llama3.2-vision` handles images automatically.\n\n### Security\n\n- Only YOUR Chat ID can interact with the bot\n- No open ports required (polling mode)\n- All traffic over HTTPS\n\n---\n\n## Google Calendar Integration\n\n### Prerequisites\n\n- A Google account\n- Docker container running (standard setup — no extra ports needed)\n\n### Setup (one-time, ~10 minutes)\n\n#### Step 1 — Google Cloud Console\n\n1. Go to [console.cloud.google.com](https://console.cloud.google.com)\n2. Create a new project (name it anything, e.g. \"TrinityClaw\")\n3. **APIs & Services → Library** → search **Google Calendar API** → Enable\n4. **APIs & Services → Credentials → + Create Credentials → OAuth client ID**\n5. If prompted to configure the consent screen:\n   - Choose **External**\n   - Fill in an app name → Save\n   - Skip Scopes → Save\n   - **Audience tab → Test users → + Add users** → add your Gmail address → Save\n6. Back at Create Credentials: select **User data**, click Next\n7. Under credential type choose **Desktop app** → Create\n8. **Download JSON** → rename the file to `gcal_credentials.json`\n\n> **Important:** On the \"What data will you be accessing?\" screen, choose **User data** (not Application data). Application data creates a service account which won't work for personal calendars.\n\n#### Step 2 — Copy credentials into the container\n\n```powershell\n# Run from the trinity-claw folder\ndocker cp gcal_credentials.json trinity-claw-trinity-agent-1:/app/memory/gcal_credentials.json\n```\n\n#### Step 3 — Authorize (one-time browser step)\n\nTell your agent:\n> \"Authorize google calendar\"\n\nThe agent will give you a URL. Open it in your browser, sign in with the same Google account you added as a test user, click **Allow**, copy the code Google shows you, and paste it back:\n> \"authorize(PASTE_CODE_HERE)\"\n\nThe token is saved to `/app/memory/gcal_token.json` and **auto-refreshes forever** — you never need to do this again.\n\n### Usage Examples\n\nJust talk to the agent naturally:\n\n| Say to the agent | What happens |\n|---|---|\n| \"What's on my calendar this week?\" | Lists next 7 days of events |\n| \"Schedule a meeting tomorrow at 2pm for 30 minutes\" | Creates the event |\n| \"When am I free on Friday for 1 hour?\" | Finds open slots (8am–8pm window) |\n| \"Move that meeting to 3pm\" | Updates the event time |\n| \"Delete the standup event\" | Deletes by event ID |\n| \"Check google calendar status\" | Shows auth and token health |\n\n### Token Notes\n\n- The token auto-refreshes as long as `refresh_token` is present in `/app/memory/gcal_token.json`\n- If you ever see auth errors after a long time, revoke the app at [myaccount.google.com/permissions](https://myaccount.google.com/permissions) and re-run `authorize()`\n- The `gcal_credentials.json` file stays in `/app/memory/` — it survives container rebuilds because `/app/memory/` is a Docker volume\n\n---\n\n## Gmail Integration\n\nTrinityClaw supports Gmail in two modes — **sending** via SMTP (simple, works immediately) and **reading** via the Gmail API (full inbox access).\n\n---\n\n### Part 1 — Sending Email via Gmail SMTP\n\nThis is the quickest way to get email sending working.\n\n#### Step 1 — Generate a Gmail App Password\n\nRegular Gmail passwords won't work with SMTP. You need an App Password:\n\n1. Make sure **2-Factor Authentication** is enabled on your Google account:\n   → https://myaccount.google.com/security\n\n2. Generate an App Password:\n   → https://myaccount.google.com/apppasswords\n   - App name: type anything (e.g. `TrinityClaw`)\n   - Click **Create**\n   - Copy the **16-character code** Google shows you\n\n#### Step 2 — Add to .env\n\n```env\nSMTP_HOST=smtp.gmail.com\nSMTP_PORT=587\nSMTP_USER=your@gmail.com\nSMTP_PASSWORD=abcdefghijklmnop\n```\n\nThen restart:\n```bash\ndocker-compose restart trinity-agent\n```\n\n#### Usage Examples\n\nJust tell the agent naturally:\n\n| Say to the agent | What happens |\n|---|---|\n| \"Send an email to john@example.com about the meeting\" | Drafts and sends via Gmail SMTP |\n| \"Email me a summary of today's tasks\" | Sends to your configured address |\n| \"Send the report.pdf to client@company.com\" | Sends with attachment |\n\n---\n\n### Part 2 — Reading Gmail Inbox (Gmail API)\n\nFull read access to your inbox — list, search, read, download attachments.\n\n#### Prerequisites\n\n- Google Cloud project already set up (same one used for Calendar)\n- `gcal_credentials.json` already in `/app/memory/`\n\n#### Step 1 — Enable Gmail API\n\nGo to: https://console.cloud.google.com/apis/library/gmail.googleapis.com\n\nClick **Enable** (same project as Calendar — no new credentials needed).\n\n#### Step 2 — Authorize (one-time)\n\nTell your agent:\n> \"authorize gmail\"\n\nThe agent will give you a URL. Open it, sign in, click **Allow**, copy the code, and paste it back:\n> \"authorize gmail with CODE\"\n\nToken saved to `/app/memory/gmail_token.json` — auto-refreshes forever.\n\n#### Usage Examples\n\n| Say to the agent | What happens |\n|---|---|\n| \"Summarize my inbox\" | Shows last 10 emails with sender, subject, preview |\n| \"Do I have any unread emails from John?\" | Searches `from:john is:unread` |\n| \"Read the email about the invoice\" | Fetches and displays full body |\n| \"Download the attachments from that email\" | Saves to `memory/email_attachments/` |\n| \"Mark that as read\" | Removes UNREAD label |\n\n#### Gmail Search Operators\n\nThe agent understands all standard Gmail search operators:\n\n```\nfrom:john@example.com\nsubject:invoice\nis:unread\nhas:attachment\nafter:2026/1/1\nfrom:boss@company.com is:unread has:attachment\n```\n\n#### Token Notes\n\n- Token stored at `/app/memory/gmail_token.json` — separate from Calendar token\n- Auto-refreshes as long as a `refresh_token` is present\n- If expired: revoke at myaccount.google.com/permissions then call `authorize gmail` again\n\n---\n\n## Business Knowledge Base\n\nTeach TrinityClaw about your business by dropping documents into a folder. Once ingested, the agent searches your documents automatically before answering business questions — no manual prompting needed.\n\n### How It Works\n\n1. Drop files into `memory/knowledge/` on your host machine\n2. Tell the agent: *\"ingest my knowledge folder\"* (or call it directly)\n3. Ask questions naturally — the agent searches your docs first\n\nDocuments are chunked, embedded, and stored in a dedicated ChromaDB collection (`business_knowledge`) that is **separate from conversation memory**.\n\n### Supported File Types\n\nPDF, DOCX, DOC, XLSX, XLS, CSV, TXT, MD, JSON, YAML, XML, HTML and more.\n\n### Usage Examples\n\n```\n# Index all files in the knowledge folder\n<skill:knowledge_base.ingest_folder></skill:knowledge_base.ingest_folder>\n\n# Index a custom folder path\n<skill:knowledge_base.ingest_folder>/app/memory/knowledge/</skill:knowledge_base.ingest_folder>\n\n# Ingest a single file\n<skill:knowledge_base.ingest_file>meeting-notes-jan.docx</skill:knowledge_base.ingest_file>\n\n# Search your business documents\n<skill:knowledge_base.search>refund policy</skill:knowledge_base.search>\n\n# Search with more results\n<skill:knowledge_base.search>Q1 sales targets,10</skill:knowledge_base.search>\n\n# List everything that has been indexed\n<skill:knowledge_base.list_ingested></skill:knowledge_base.list_ingested>\n\n# Remove a document from the index\n<skill:knowledge_base.delete_document>old-contract.pdf</skill:knowledge_base.delete_document>\n\n# Check collection health\n<skill:knowledge_base.status></skill:knowledge_base.status>\n```\n\n### Re-ingestion & Change Detection\n\n`ingest_folder()` uses **MD5 hash comparison** — if a file hasn't changed since the last ingest, it is skipped automatically. Updated files are re-chunked and replaced in ChromaDB. You can safely run `ingest_folder()` as often as you want.\n\n### Automatic Behavior\n\nThe agent's identity is configured to:\n- **Always search the knowledge base first** when asked about meetings, SOPs, clients, policies, or any business-specific topic\n- **Proactively remind you** to ingest when you mention dropping or uploading files\n- **Never say \"I don't have that information\"** for business questions without searching first\n\n### Scheduling Automatic Re-ingestion\n\nUse the `scheduler` skill to keep the knowledge base fresh automatically:\n\n```\n# Re-ingest every morning at 8am\n<skill:scheduler.schedule_recurring>kb_sync,24h,ingest my knowledge folder</skill:scheduler.schedule_recurring>\n```\n\n---\n\n## API Reference\n\n### Endpoints\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| `GET` | `/health` | System health check |\n| `GET` | `/skills` | List all loaded skills |\n| `POST` | `/skills/reload` | Reload skills from core/ and dynamic/ (no auth required) |\n| `POST` | `/skill/call` | Call a skill function |\n| `POST` | `/chat` | Send message to agent (supports `image` field for vision) |\n| `POST` | `/transcribe` | Transcribe base64 audio via local Whisper |\n\n### Examples\n\n**Health check:**\n```bash\ncurl http://localhost:8001/health\n```\n\n**List skills:**\n```bash\ncurl http://localhost:8001/skills\n```\n\n**Chat with agent:**\n```bash\ncurl -X POST http://localhost:8001/chat \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"message\": \"Hello TrinityClaw!\"}'\n```\n\n**Call skill directly:**\n```bash\ncurl -X POST http://localhost:8001/skill/call \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"skill\": \"notes\", \"function\": \"list\", \"args\": []}'\n```\n\n---\n\n## Persistent Memory System\n\nTrinityClaw builds a growing model of you and your work across every session. Memory is layered (see also **Memory & Autonomy** above for the capped stores and session snapshot):\n\n| Layer | What's stored | Where |\n|-------|--------------|-------|\n| **Notes** | Free-form notes and saved research | `memory/notes.json` |\n| **User model** | Preferences, patterns, context, rejected ideas | `memory/user_model.json` |\n| **Agent memory store** | Curated agent/project facts (capped) | `memory/MEMORY.md` |\n| **User profile store** | Curated user-profile facts (capped) | `memory/USER.md` |\n| **Goals** | Open and completed goals with optional due dates | `memory/user_model.json` (goals array) |\n| **Daily journal** | End-of-day summaries, learnings, next steps | `memory/daily_journal.jsonl` |\n| **Lessons** | Per-skill failure/fix records used by autoimprove | `memory/lessons.jsonl` |\n| **Activity log** | Rolling action log (24h window) | `memory/activity_log.jsonl` |\n| **Heartbeat audit** | One JSON row per ambient tick (verdict + summary + tokens) | `memory/heartbeat.jsonl` |\n| **Open loops** | Unfinished promises and follow-ups (14-day expiry) | `memory/open_loops.json` |\n| **Session checkpoints** | Last-session context for continuity (last 10) | `memory/session_checkpoints.json` |\n| **Improvement log** | Every autoimprove experiment with outcome + scores | `memory/improvement_log.jsonl` |\n| **ChromaDB** | Semantic vector index of all past context | `memory/databases/` |\n\n### Daily Journal — `notes.end_day()`\n\nAt 23:00 every night (scheduled automatically) the agent writes a journal entry. You can also trigger it manually:\n\n```\nnotes.end_day(\n  summary=\"What was accomplished today\",\n  next_steps=\"Pending items or plans for tomorrow\",\n  user_insights=\"Patterns observed about your focus areas\"\n)\n```\n\nThe journal lives at `memory/daily_journal.jsonl` (one JSON line per day). The agent reaches it three ways: the last-conversation checkpoint in the session snapshot, `notes.get_last_logs()` / `notes.search_logs()` on demand, and in the raw tick context of its own heartbeat — recent-work questions are answered by searching/recalling, not by wholesale injection.\n\n### Goal Tracking — `notes.add_goal()` / `notes.list_goals()`\n\nTrack ongoing objectives across sessions:\n\n```\n# Add a goal\nnotes.add_goal(\"Launch the new landing page\", due_date=\"2026-05-01\")\n\n# List open goals\nnotes.list_goals()\n\n# Mark done\nnotes.complete_goal(\"landing page\")\n```\n\nActive goals are automatically injected into the session context so the agent stays oriented toward what matters.\n\n### Weekly Meta-Review — `meta_review.weekly_digest()`\n\nEvery Saturday at 08:00 (scheduled automatically) the agent synthesizes all memory files into a single report covering:\n- Top recurring error types and whether fixes exist\n- Lesson fix-coverage rate (how many failures have been addressed)\n- Which autoimprove loops are actually producing improvements (ROI)\n- Recent journal themes and next steps\n\nRun it manually anytime:\n\n```\nmeta_review.weekly_digest(7)       ← last 7 days\nmeta_review.loop_roi_report()      ← per-loop improvement breakdown\nmeta_review.error_trend_report(30) ← error frequency + fix coverage\n```\n\nCritical findings (unfixed high-frequency errors, low fix coverage) are parked as improvement ideas automatically.\n\n---\n\n## AutoImprove — Overnight Self-Improvement\n\n`autoimprove` is a dynamic skill that runs autoresearch-style loops while you sleep. It continuously audits your skills, auto-fixes safe issues, queues suggestions for your review, and can research any topic on the web.\n\n### How it works\n\n**Two-track system:**\n- **Dynamic skills** → auto-fix: snapshot → patch → test → keep or restore\n- **Core skills** → suggest only: audit → save patch to memory → you approve\n\n---\n\n### Quick start\n\nTell Trinity:\n```\nautoimprove.status()\n```\n\nPut it on autopilot:\n```\nautoimprove.schedule_nightly(\"2am\")\n```\n\nCheck results in the morning:\n```\nautoimprove.report(1)\nautoimprove.list_suggestions()\n```\n\n---\n\n### Research — any topic\n\n`research()` is a general-purpose web research function. Give it any query and it searches the web, fetches the top pages, extracts key content, and saves findings to your notes automatically.\n\n```\nautoimprove.research(\"Python async best practices\")\nautoimprove.research(\"how to improve Playwright reliability\", depth=\"deep\")\nautoimprove.research(\"latest trends in local LLM models\", depth=\"deep\", save=True)\n```\n\n**Parameters:**\n| Parameter | Options | Description |\n|-----------|---------|-------------|\n| `query` | any string | What to research — topic, question, error message, concept |\n| `depth` | `'quick'` (default) | 1 search + fetches top 2 pages (~15s) |\n| | `'deep'` | 3 search variations + fetches top 5 pages (~45s) |\n| `save` | `True` (default) | Saves findings to notes with a timestamped title |\n\nResults are always saved to `memory/notes.json` under `\"Research — [query] — [date]\"` so they persist across sessions and can be retrieved with `notes.search(\"research\")`.\n\n---\n\n### Improvement loops\n\n| Loop | What it does | Modifies files? |\n|------|-------------|-----------------|\n| `daily_review` | Reads lessons.jsonl, surfaces recurring patterns | No |\n| `ast_audit` | Fixes `bare_except` and `missing_timeout` in dynamic skills | Yes (dynamic only) |\n| `error_reduce` | Targets the most-frequent error pattern across dynamic skills | Yes (dynamic only) |\n| `suggest_core` | Audits all 30+ core skills, queues patches for your approval | No |\n\nRun all loops at once:\n```\nautoimprove.run_all(5)       ← max 5 experiments per loop\n```\n\nRun a single loop:\n```\nautoimprove.run_loop(\"ast_audit\", 10)\nautoimprove.run_loop(\"suggest_core\", 30)\n```\n\n---\n\n### Core skill suggestions\n\nThe nightly run scans all core skills and queues proposed fixes. Nothing is applied automatically — you review and approve each one.\n\n```\n# See what's pending\nautoimprove.list_suggestions()\n\n# See all (including applied and failed)\nautoimprove.list_suggestions(\"all\")\n\n# Apply one approved suggestion to a core skill\nautoimprove.apply_suggestion(\"browser_session\", \"bare_except\")\nautoimprove.apply_suggestion(\"web\", \"missing_timeout\")\n```\n\nEach `apply_suggestion()` call:\n1. Snapshots the core skill file\n2. Applies the patch\n3. Runs a runtime smoke test\n4. Keeps the file if test passes, restores snapshot if it fails\n\n---\n\n### Single experiment\n\nTest one specific fix on a dynamic skill:\n```\nautoimprove.run_experiment(\"seo_analyzer\", \"bare_except\")\nautoimprove.run_experiment(\"content_calendar\", \"missing_timeout\")\n```\n\n---\n\n### View history\n\n```\nautoimprove.report(7)     ← last 7 days\nautoimprove.report(1)     ← last 24 hours (useful after a nightly run)\nautoimprove.report(30)    ← last month\n```\n\n---\n\n### Memory files\n\n| File | Contents |\n|------|----------|\n| `memory/improvement_log.jsonl` | Every experiment — outcome, scores, timestamps. Read by `meta_review.loop_roi_report()` |\n| `memory/core_suggestions.jsonl` | Pending/applied/failed suggestions for core skills |\n| `memory/lessons.jsonl` | Per-skill failure/fix records. Read by `meta_review.weekly_digest()` |\n| `memory/notes.json` | Research findings saved by `research()` |\n\n---\n\n## Project Structure\n\n```\ntrinity-claw/\n├── docker-compose.yml          # Docker orchestration\n├── setup.bat                   # Windows installer alternative (double-click, from GitHub Releases)\n├── install.ps1                 # Windows installer (run via Win+R one-liner or setup.bat)\n├── install.sh                  # Linux/Mac installer\n├── .env                        # Secrets (not in git)\n├── .env.example                # Secrets template\n├── identity.md                 # Agent personality and standing orders (editable)\n├── README.md                   # This file\n│\n├── agent/                      # TrinityClaw agent\n│   ├── Dockerfile\n│   ├── app.py                  # Main application\n│   ├── requirements.txt\n│   ├── ollama-entrypoint.sh    # Auto-pulls local model on startup\n│   └── skills/\n│       ├── __init__.py\n│       ├── core/               # System skills (read-only)\n│       │   ├── notes.py\n│       │   ├── files.py\n│       │   ├── web.py\n│       │   ├── code_executor.py\n│       │   ├── create_skill.py\n│       │   ├── git_manager.py\n│       │   ├── scheduler.py\n│       │   ├── document_parser.py\n│       │   ├── data_science.py\n│       │   ├── image_viewer.py\n│       │   ├── url_monitor.py\n│       │   ├── self_improvement.py\n│       │   ├── dashboard.py\n│       │   ├── terminal.py\n│       │   ├── telegram_bot.py\n│       │   ├── email_sender.py\n│       │   ├── web_builder.py\n│       │   ├── google_calendar.py\n│       │   ├── knowledge_base.py\n│       │   ├── gmail_reader.py\n│       │   ├── competitive_intel.py\n│       │   ├── google_drive.py\n│       │   ├── meeting_notes.py\n│       │   ├── youtube.py\n│       │   ├── autoimprove.py  # Autoresearch loops + web research (see AutoImprove section)\n│       │   ├── meta_review.py  # Weekly synthesis: errors, loop ROI, journal themes\n│       │   ├── memory.py       # Capped MEMORY.md/USER.md stores (see Memory & Autonomy)\n│       │   ├── memory_search.py # Recall past sessions (FTS5) + semantic memory search\n│       │   ├── open_loops.py   # Promise/follow-up tracking (see Memory & Autonomy)\n│       │   ├── heartbeat.py    # Ambient idle-time daemon config (see Ambient Heartbeat)\n│       │   ├── mcp_client.py   # MCP client (see MCP Client section)\n│       │   ├── composio.py     # Composio integration (see Composio section)\n│       │   └── _user_model_store.py  # Internal: user model data layer (used by notes.py)\n│       └── dynamic/            # User skills (AI agent can read-write)\n│\n├── config/\n│   └── litellm_config.yaml     # LLM configuration\n│\n├── memory/                     # Persistent storage (excluded from git except items below)\n│   ├── scheduled_tasks1.json   # Starter scheduled task config — rename to scheduled_tasks.json on first run\n│   ├── knowledge/              # Drop business documents here for ingestion\n│   └── websites/               # web_builder projects (served on port 8090)\n│\n└── web/\n    └── index.html              # Web UI\n```\n\n---\n\n## Maintenance\n\n### Basic Commands\n\n```bash\n# Start services\ndocker-compose up -d\n\n# Stop services\ndocker-compose down\n\n# Restart services\ndocker-compose restart\n\n# View logs\ndocker logs trinity-claw-trinity-agent-1 --tail 50\n\n# Rebuild after adding core skills\ndocker-compose down\ndocker-compose build --no-cache trinity-agent\ndocker-compose up -d\n```\n\n### Backup\n\n```bash\n# Backup memory\ncp -r memory/ backup_$(date +%Y%m%d)/\n\n# Backup everything\ntar -czvf trinity_backup_$(date +%Y%m%d).tar.gz memory/ config/ .env\n```\n\n### Reset\n\n```bash\n# Soft reset (keeps memory)\ndocker-compose down\ndocker-compose up -d\n\n# Hard reset (deletes everything!)\ndocker-compose down -v\nrm -rf memory/\ndocker-compose up -d\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n| Issue | Solution |\n|-------|----------|\n| **Port 8001 in use** | Change port in `docker-compose.yml` |\n| **Skill not found** | Run `POST /skills/reload` or rebuild |\n| **Memory errors** | Increase Docker memory limit to 4GB+ |\n| **API errors** | Check `.env` has correct API key |\n| **Telegram not responding** | Verify token and chat ID, check logs |\n| **Google Calendar auth loop** | Run `docker compose build trinity-agent` then `docker compose up -d` to pick up the latest skill code, then re-authorize |\n| **Google Calendar invalid_grant** | Each code is single-use and expires in 10 min. Call `authorize()` again for a fresh URL |\n| **Google Calendar token expired** | Revoke at myaccount.google.com/permissions, then call `authorize()` again |\n| **Google Calendar Access blocked** | Add your Gmail to Test Users: Google Cloud Console → APIs & Services → OAuth consent screen → Audience → Test users |\n| **Ollama model not pulled / missing** | Mac: run `ollama pull qwen3.5:9b`. Linux: the pull runs automatically in `ollama-init` on first startup (~6.6GB) — check progress with `docker logs trinity-claw-ollama-init-1 -f`. To pull manually: `docker exec trinity-claw-ollama-1 ollama pull qwen3.5:9b` |\n| **Voice not transcribed** | First use downloads Whisper model — wait up to 2 min. Check logs: `docker logs trinity-claw-trinity-agent-1 \\| grep -i whisper` |\n| **Image described incorrectly** | Ensure `trinity-vision` in `litellm_config.yaml` points to a vision-capable model, then `docker compose restart litellm` |\n| **Browser skill not working** | Rebuild the container: `docker-compose build --no-cache trinity-agent && docker-compose up -d`. Chromium installs during build. |\n| **Browser times out on JS pages** | Try `browser_goto` with `wait_until=load` instead of `networkidle` for heavy SPAs |\n| **Gmail not authorized** | Run `gmail.authorize()`, open the URL, click Allow, paste the code back. |\n| **Gmail token expired** | Revoke at myaccount.google.com/permissions then call `gmail.authorize()` again. |\n| **Gmail API not enabled** | Go to Google Cloud Console → APIs & Services → Library → Gmail API → Enable. |\n| **Knowledge base not finding results** | Run `ingest_folder()` first. Check `status()` to confirm ChromaDB is connected. |\n| **Search returns no results / blocked** | Set `TAVILY_API_KEY` in `.env` for reliable search. Without it, `search()` falls back to DuckDuckGo → Bing scraping which can be rate-limited. |\n| **Knowledge base ChromaDB error** | Ensure ChromaDB container is running: `docker-compose ps`. Restart with `docker-compose restart chroma`. |\n| **File not ingested** | Check the file extension is supported (`list_supported` via `document_parser`). PDF needs `pdfplumber` — it's in `requirements.txt`. |\n| **MCP server won't connect** | Run `test_server(\"<name>\")` for full diagnostics. HTTP 401/403 = token rejected — check the key in `.env`. For stdio servers: verify the command runs inside the container. For SSE servers: try the modern `http` transport instead. |\n\n### Debug Commands\n\n```bash\n# Check container status\ndocker-compose ps\n\n# View agent logs\ndocker logs trinity-claw-trinity-agent-1 --tail 100\n\n# Check LiteLLM logs\ndocker logs trinity-claw-litellm-1 --tail 100\n\n# Test API\ncurl http://localhost:8001/health\n\n# List loaded skills\ncurl http://localhost:8001/skills\n```\n\n---\n\n## Contributing\n\n1. Fork the repository\n2. Create feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit changes (`git commit -m 'Add amazing feature'`)\n4. Push to branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n---\n\n## License\n\nMIT License - see LICENSE file for details.\n\n---\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/TrinityClaw/trinity-claw/issues)\n- **Discussions**: [GitHub Discussions](https://github.com/TrinityClaw/trinity-claw/discussions)\n\n---\n\n**Version**: TrinityClaw v1.4.0\n**Last Updated**: 2026-10-04"}