Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 15 additions & 41 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ on:
branches: [main]

jobs:
lint:
runs-on: ubuntu-latest
check:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}

steps:
- name: Checkout code
Expand All @@ -29,46 +32,17 @@ jobs:
uses: actions/cache@v5
with:
path: .venv
key: venv-${{ runner.os }}-3.11-${{ hashFiles('**/poetry.lock') }}
key: venv-${{ runner.os }}-3.11-${{ hashFiles('poetry.lock') }}

- name: Install dependencies
run: poetry lock && poetry install
- name: Validate committed lock
run: poetry check --lock

- name: Check formatting (black)
run: poetry run black --check src tests
- name: Install committed dependencies
run: poetry sync

- name: Check import order (isort)
run: poetry run isort --check-only src tests
- name: Run required checks
run: make lint test test-deploy

- name: Lint (flake8)
run: poetry run flake8 src tests

test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Python 3.11
uses: actions/setup-python@v6
with:
python-version: "3.11"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true

- name: Cache dependencies
uses: actions/cache@v5
with:
path: .venv
key: venv-${{ runner.os }}-3.11-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
run: poetry lock && poetry install

- name: Test
run: make test
- name: Verify direct systemd unit
if: runner.os == 'Linux'
run: bash tests/deploy/test_systemd_unit.sh
19 changes: 18 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ make install # Production deps only
make run # Run the bot
make run-debug # Run with debug logging
make test # Run tests with coverage
make lint # Black + isort + flake8 + mypy
make check # Committed lock + format + lint + tests + deploy tests
make lint # Black + isort + flake8
make format # Auto-format with black + isort

# Run a single test
Expand All @@ -24,6 +25,22 @@ poetry run pytest tests/unit/test_config.py -k test_name -v
poetry run mypy src
```

`make typecheck` is informative until the existing mypy debt is resolved. Do not
weaken mypy or describe it as passing. Required CI checks are defined by `make check`.

## Fork workflow and deployment boundary

Development happens in a local macOS checkout. `origin` is this fork and is the only
remote that receives pushes. `upstream` is fetch-only. Read
[`docs/fork-workflow.md`](docs/fork-workflow.md) before branch or remote work.

The `mybots` host only runs production and accepts explicit commits already on
`origin/main`. It must not create branches, commits, lock changes, or development
environments. Use the tracked scripts in `ops/` and follow
[`docs/deployment.md`](docs/deployment.md). Releases are immutable per-SHA directories;
the stable direct unit follows one atomic `current` selector. The first cutover retains
the legacy checkout until separate human decommissioning.

## Architecture

### Claude SDK Integration
Expand Down
12 changes: 5 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ This project is currently under active development with the following status:

4. **Verify setup**:
```bash
make test
make lint
make check
```

## Development Workflow
Expand Down Expand Up @@ -94,7 +93,7 @@ This project is currently under active development with the following status:
3. **Follow code standards**:
```bash
make format # Auto-format code
make lint # Check code quality
make lint # Check formatting and lint
```

4. **Update documentation** as needed
Expand Down Expand Up @@ -222,8 +221,7 @@ async def test_feature():

1. **Ensure tests pass**:
```bash
make test
make lint
make check
```

2. **Update documentation** if needed
Expand Down Expand Up @@ -360,7 +358,7 @@ Instead:
- **Black**: Code formatting
- **isort**: Import sorting
- **flake8**: Linting
- **mypy**: Type checking
- **mypy**: Strict type checking, run separately while existing debt remains
- **pytest**: Testing

### Recommended IDE Setup
Expand Down Expand Up @@ -414,7 +412,7 @@ Instead:
### Debugging
- Use `make run-debug` for detailed logging
- Check test output with `make test`
- Run type checking with `poetry run mypy src`
- Run the optional type check with `make typecheck`

## Recognition

Expand Down
43 changes: 19 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: install dev test lint format clean help run run-watch run-remote remote-attach remote-stop \
.PHONY: install dev test lint typecheck check check-lock test-deploy format clean help run run-watch \
bump-patch bump-minor bump-major release version

# Default target
Expand All @@ -8,6 +8,8 @@ help:
@echo " dev - Install development dependencies"
@echo " test - Run tests"
@echo " lint - Run linting checks"
@echo " typecheck - Run mypy (known debt is tracked separately)"
@echo " check - Run the same required checks as CI"
@echo " format - Format code"
@echo " clean - Clean up generated files"
@echo " run - Run the bot"
Expand All @@ -17,12 +19,9 @@ help:
@echo " bump-minor - Bump minor version (1.2.0 -> 1.3.0), commit, and tag"
@echo " bump-major - Bump major version (1.2.0 -> 2.0.0), commit, and tag"
@echo " release - Push current version tag to trigger release workflow"
@echo " run-remote - Start bot in tmux on remote Mac (unlocks keychain)"
@echo " remote-attach - Attach to running bot tmux session"
@echo " remote-stop - Stop the bot tmux session"

install:
poetry install --no-dev
poetry sync --only main

dev:
poetry install
Expand All @@ -32,14 +31,24 @@ test:
poetry run pytest

lint:
poetry run black --check src tests
poetry run isort --check-only src tests
poetry run flake8 src tests
poetry run black --check src tests ops
poetry run isort --check-only src tests ops
poetry run flake8 src tests ops

typecheck:
poetry run mypy src

check-lock:
poetry check --lock

test-deploy:
poetry run pytest tests/deploy

check: check-lock lint test test-deploy

format:
poetry run black src tests
poetry run isort src tests
poetry run black src tests ops
poetry run isort src tests ops

clean:
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
Expand All @@ -57,20 +66,6 @@ run-watch: ## Run the bot with auto-restart on src/ changes (uses watchfiles)
run-debug:
poetry run claude-telegram-bot --debug

# Remote Mac Mini (SSH session)
run-remote: ## Start bot on remote Mac in tmux (persists after SSH disconnect)
security unlock-keychain ~/Library/Keychains/login.keychain-db
tmux new-session -d -s claude-bot 'poetry run claude-telegram-bot'
@echo "Bot started in tmux session 'claude-bot'"
@echo " Attach: make remote-attach"
@echo " Stop: make remote-stop"

remote-attach: ## Attach to running bot tmux session
tmux attach -t claude-bot

remote-stop: ## Stop the bot tmux session
tmux kill-session -t claude-bot

# --- Version Management ---

version: ## Show current version
Expand Down
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,24 +131,21 @@ Use `/verbose 0|1|2` to control how much background activity is shown:

#### GitHub Workflow

Claude Code already knows how to use `gh` CLI and `git`. Authenticate on your server with `gh auth login`, then work with repos conversationally:
Claude Code can use `gh` and Git when the installation grants those tools. In this
fork, development happens in the local macOS checkout. The production host is not a
development workspace and does not push, create branches, or make commits. See
[`docs/fork-workflow.md`](docs/fork-workflow.md).

```
You: List my repos related to monitoring
Bot: [Claude runs gh repo list, shows results]

You: Clone the uptime one
Bot: [Claude runs gh repo clone, clones into workspace]

You: /repo
Bot: 📦 uptime-monitor/ ◀
📁 other-project/

You: Show me the open issues
Bot: [Claude runs gh issue list]

You: Create a fix branch and push it
Bot: [Claude creates branch, commits, pushes]
```

Use `/repo` to list cloned repos in your workspace, or `/repo <name>` to switch directories (sessions auto-resume).
Expand Down Expand Up @@ -332,7 +329,9 @@ See [SECURITY.md](SECURITY.md) for details.
```bash
make dev # Install all dependencies
make test # Run tests with coverage
make lint # Black + isort + flake8 + mypy
make lint # Black + isort + flake8
make typecheck # mypy (existing debt is tracked separately)
make check # Same required checks as CI
make format # Auto-format code
make run-debug # Run with debug logging
make run-watch # Run with auto-restart on code changes
Expand All @@ -356,7 +355,7 @@ Each command commits, tags, and pushes automatically, triggering CI tests and a

1. Fork the repository
2. Create a feature branch: `git checkout -b feature/amazing-feature`
3. Make changes with tests: `make test && make lint`
3. Make changes with tests: `make check`
4. Submit a Pull Request

**Code standards:** Python 3.11+, Black formatting (88 chars), type hints required, pytest with >85% coverage.
Expand Down
Loading