Metadata-Version: 2.4
Name: autobot-cli
Version: 0.1.0
Summary: Agent gateway wrapping Claude Code CLI for Telegram + Cron
License-Expression: MIT
Requires-Python: >=3.11
Requires-Dist: aiosqlite>=0.20.0
Requires-Dist: apscheduler>=3.11.0
Requires-Dist: fastapi>=0.116.0
Requires-Dist: mcp>=1.9.0
Requires-Dist: orjson>=3.10.0
Requires-Dist: pydantic>=2.11.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: python-telegram-bot>=21.11
Requires-Dist: pyyaml>=6.0
Requires-Dist: uvicorn[standard]>=0.34.0
Requires-Dist: watchfiles>=1.0.0
Provides-Extra: hybrid
Requires-Dist: numpy>=2.1.0; extra == 'hybrid'
Requires-Dist: qdrant-client>=1.12.0; extra == 'hybrid'
Description-Content-Type: text/markdown

# Clawde

An OpenClaw-like gateway that turns the **Claude Code CLI** (`claude`) into an always-on automation agent with Telegram integration, cron scheduling, and persistent memory.

## How it works

```
Telegram message ──▶ clawde gateway ──▶ claude -p --resume <session> ──▶ JSON response ──▶ Telegram reply
                                                                          └──▶ actions (schedule job, write memory, …)

Cron trigger ──▶ clawde gateway ──▶ claude -p --no-session-persistence ──▶ JSON response ──▶ optional Telegram post
```

- **Telegram chats are sessionful** — each chat gets its own Claude Code session, restored on every message via `--resume`.
- **Cron jobs are stateless** — scheduled runs use `--no-session-persistence`.
- **Memory is file-based** — lives in `memory/`, injected into each run by the gateway.
- **Claude outputs structured JSON** — the gateway parses it and executes any requested actions (scheduling jobs, writing memories, etc).

## Prerequisites

- **Python 3.11+**
- **Claude Code CLI** (`claude`) installed and authenticated — [install instructions](https://docs.anthropic.com/en/docs/claude-code)
- A **Telegram Bot Token** from [@BotFather](https://t.me/BotFather)

## Installation

```bash
# Clone the repo
git clone <your-repo-url> clawde
cd clawde

# Create a virtual environment
python -m venv .venv
# Linux/macOS:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate

# Install dependencies
pip install pydantic pyyaml aiosqlite python-telegram-bot apscheduler orjson
```

> Optional: install `rich` for nicer CLI output.

## Running with Docker

Docker and compose files live in `docker/`:

```bash
cd docker
copy .env.example .env   # Windows
# cp .env.example .env    # Linux/macOS
docker compose --env-file ./.env -f docker-compose.yml up -d --build
```

Default host ports are non-conflicting with local defaults:
- Dashboard: `18420`
- Manager API: `18421`
- Qdrant: `18433`

Set different `CLAWDE_*_HOST` values in `docker/.env` if needed.

For local + docker side-by-side on one machine, use different Telegram bot tokens per instance to avoid session/token collisions.

## Quick start

### 1. Initialize the project

```bash
python -m clawde_app.cli init
```

This creates:
- `data/config.yaml` — sample configuration (you must edit this)
- `memory/` — memory directory scaffold
- `runtime/` — logs and transient context directory

### 2. Configure

Edit `data/config.yaml`:

```yaml
telegram:
  bot_token: "YOUR_TELEGRAM_BOT_TOKEN"    # <-- paste your token here
  allowed_chat_ids: []                     # empty = allow all (pair via /pair)
  admin_chat_ids: []                       # admin chat IDs for /mode, /jobs commands

claude:
  executable: "claude"                     # path to claude CLI if not on PATH
  model: null                              # override model (e.g. "claude-sonnet-4-5-20250929")
  max_turns_telegram: 6
  max_turns_cron: 10

memory:
  daily_include_days: 2
  retrieval:
    strategy: "keyword"
    max_snippets: 6

scheduler:
  timezone: "Europe/London"                # your timezone

security:
  secrets_path_globs:
    - "data/*"
    - ".env"
```

### 3. Check your environment

```bash
python -m clawde_app.cli doctor
```

This verifies:
- Python version is 3.11+
- Config file loads correctly
- `claude` CLI is installed and reachable
- Telegram bot token is set

### 4. Run

```bash
python -m clawde_app.cli run
```

The gateway starts polling Telegram and activates the cron scheduler. Press `Ctrl+C` to stop gracefully.

## Telegram commands

Once running, interact with your bot in Telegram:

| Command | Description |
|---------|-------------|
| `/help` | Show available commands |
| `/status` | Show current chat status (session, tool profile, pairing) |
| `/pair <code>` | Pair this chat (if allowlist is enforced) |
| `/mode <profile>` | Switch tool profile (`safe_chat`, `read_only`, `dev`) |
| `/jobs` | List scheduled cron jobs |
| `/job <id>` | Show details for a specific job |
| `/memory` | Show recent memory entries |

Any regular text message is forwarded to Claude via the gateway.

## Tool profiles

Tool profiles control what Claude Code tools are available during a run:

| Profile | Tools | Use case |
|---------|-------|----------|
| `safe_chat` | None | Pure conversation, no file/shell access |
| `read_only` | Read, Grep, Glob | Can read the codebase but not modify it |
| `dev` | Read, Edit, Bash, Grep, Glob | Full development access (admin only) |

Switch profiles per-chat with `/mode <profile>`.

## Cron jobs

Claude can request cron jobs via structured actions in its JSON output. Jobs are stored in SQLite and managed by APScheduler.

Schedule types:
- **cron** — standard cron expression (e.g., `"0 9 * * *"` = daily at 9am)
- **interval** — repeat every N seconds/minutes/hours
- **once** — fire once at a specific datetime

Cron job output can be posted to a Telegram chat, and the gateway automatically ingests those messages into the chat's session so Claude "remembers" what cron jobs reported.

## Memory system

The `memory/` directory holds durable knowledge:

```
memory/
  MEMORY.md          # curated index / key facts
  topics/
    projects.md      # topic-specific memory files
    preferences.md
    systems.md
  daily/
    2026-02-07.md    # daily logs
    2026-02-06.md
```

The gateway uses keyword-based retrieval to select relevant memory snippets and injects them into each Claude run via `--append-system-prompt-file`

## Project structure

```
clawde_app/
  __init__.py            # package version
  cli.py                 # CLI entrypoint (init, doctor, run)
  main.py                # async runner, signal handling, startup
  config.py              # YAML config loading, Pydantic models
  db.py                  # SQLite database (chats, events, jobs, runs)
  models.py              # enums, Pydantic models, JSON schema
  claude_runner.py       # wraps `claude -p` subprocess calls
  context_builder.py     # builds runtime/context/current.md per run
  memory_retrieval.py    # keyword-based memory search + injection
  actions.py             # executes structured actions from Claude
  telegram_service.py    # Telegram bot polling + command handlers
  scheduler_service.py   # APScheduler cron job management
  formatting.py          # Telegram HTML formatting + message splitting
  security.py            # pairing codes, secret detection, bash deny
  utils.py               # logging setup, file utilities

.claude/
  rules/                 # Claude Code rules (identity, safety, output schema)
  settings.json          # permission deny list + PreToolUse hooks
  hooks/                 # security hooks (deny secrets, deny dangerous bash)

data/                    # config + database (gitignored, sensitive)
memory/                  # persistent memory (safe to read)
runtime/                 # logs + transient context (regenerated each run)
```

## Security

- **Secrets are protected**: `data/`, `.env`, key files are blocked by both `.claude/settings.json` deny rules and PreToolUse hooks.
- **Dangerous commands are blocked**: destructive shell commands (`rm -rf /`, `format`, `shutdown`, pipe-to-shell) are denied by a Bash hook.
- **Pairing system**: optionally require chats to pair with a one-time code before accepting messages.
- **Tool profiles**: limit what Claude can do per-chat.

## License

MIT
