From cb2041fc569ee89aaaf9874090614a7d70114697 Mon Sep 17 00:00:00 2001 From: matt2dev Date: Tue, 21 Jul 2026 20:48:30 +0300 Subject: [PATCH] Scope down to local Docker testing, drop Gitea/K3s plumbing for now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a pilot project — running it via docker compose locally is enough for now. Deploy/CI can come back once the project is greenlit for real use. Also fixes claude invocation: add --strict-mcp-config (verified against the actual installed claude-code CLI --help) so only agent-news' own MCP server is loaded, not whatever else might be discoverable in the environment. Co-Authored-By: Claude Sonnet 5 --- .env.example | 2 + .gitea/workflows/build.yaml | 37 ------------------- .gitignore | 1 + README.md | 73 ++++++++++++++++++------------------- bot/lib/claude_runner.dart | 1 + docker-compose.yml | 12 ++++++ 6 files changed, 52 insertions(+), 74 deletions(-) create mode 100644 .env.example delete mode 100644 .gitea/workflows/build.yaml create mode 100644 docker-compose.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2384c46 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +TELEGRAM_BOT_TOKEN= +ALLOWED_CHAT_IDS= diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml deleted file mode 100644 index b6206d9..0000000 --- a/.gitea/workflows/build.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build & Deploy - -on: - push: - branches: [main] - -env: - REGISTRY: registry.service.bearsdev.tech - IMAGE: agent-news - REPO: platformteam-projects/agent-news - -jobs: - build: - runs-on: [ubuntu-latest] - steps: - - name: Build & Push - run: | - git clone https://gitea_admin:${{ secrets.CI_TOKEN }}@gitea.service.bearsdev.tech/${{ env.REPO }}.git app - cd app && git checkout ${{ gitea.sha }} - echo "${{ secrets.NEXUS_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.NEXUS_USERNAME }}" --password-stdin - docker buildx build \ - --builder default \ - -f runner/Dockerfile \ - -t ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ gitea.run_number }} \ - -t ${{ env.REGISTRY }}/${{ env.IMAGE }}:latest \ - --push . - - - name: Update deploy repo - run: | - git clone https://gitea_admin:${{ secrets.CI_TOKEN }}@gitea.service.bearsdev.tech/deploy/${{ env.IMAGE }}.git deploy - cd deploy - sed -i "s|image: ${{ env.REGISTRY }}/${{ env.IMAGE }}:.*|image: ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ gitea.run_number }}|" deployment.yaml - git config user.email "ci@bearsdev.tech" - git config user.name "Gitea CI" - git add deployment.yaml - git commit -m "ci: update image to ${{ env.IMAGE }}:${{ gitea.run_number }}" || echo "no changes" - git push https://gitea_admin:${{ secrets.DEPLOY_TOKEN }}@gitea.service.bearsdev.tech/deploy/${{ env.IMAGE }}.git main diff --git a/.gitignore b/.gitignore index a8c7d1d..8af25df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .dart_tool/ build/ +.env diff --git a/README.md b/README.md index cd148fa..572bcc4 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,58 @@ # agent-news Telegram-бот на Dart: по команде `/news` (или `/news <тема>`) запускает Claude Code -для ресёрча и присылает выжимку в чат. Учебный проект для platformteam — архитектура -и урок описаны в [aidoc](https://aidoc.platformteam.tech), страница `practices/agent-news-bot`. +для ресёрча и присылает выжимку в чат. Тестовый/учебный проект — пока гоняем локально +в Docker, без деплоя в кластер. ## Как это работает -Один под, один контейнер, три процесса: +Один контейнер, три процесса: 1. `agent-news-bot` (Dart, long polling) — слушает `/news`, спавнит `claude` как сабпроцесс. 2. `claude` (Claude Code CLI) — делает ресёрч, в конце вызывает MCP-тул `send_to_telegram`. 3. `agent-news-mcp` (Dart, stdio MCP-сервер) — спавнится самим `claude`, шлёт готовый текст в Telegram Bot API. -Подробности и диаграммы — в уроке aidoc. +## Запуск локально -## Локальная разработка +```bash +cp .env.example .env +# заполнить TELEGRAM_BOT_TOKEN и ALLOWED_CHAT_IDS (через запятую) + +docker compose up -d --build +``` + +`~/.claude` (авторизация Claude Code) хранится в именованном volume `claude-home` — +переживает пересборку и рестарт контейнера. + +### Первичная авторизация Claude Code + +Claude Code CLI использует OAuth-логин через Claude.ai (подписка, не API-ключ). Один раз +после первого запуска нужно зайти в контейнер и залогиниться: + +```bash +docker compose exec agent-news claude +``` + +CLI напечатает ссылку — открой её в браузере, авторизуйся. Токен сохранится в +`~/.claude` на volume, так что после `docker compose restart` логин не слетит. + +### Проверка + +Напиши боту `/news` (или `/news <тема>`) из чата с id из `ALLOWED_CHAT_IDS` — бот +ответит "ищу…", а через 1-3 минуты Claude сам пришлёт выжимку через `send_to_telegram`. + +```bash +docker compose logs -f agent-news +``` + +## Локальная разработка (без Docker) ```bash cd bot && dart pub get && dart analyze cd ../mcp_server && dart pub get && dart analyze ``` -Сборка образа (контекст — корень репозитория): - -```bash -docker build -f runner/Dockerfile -t agent-news:dev . -``` - ## Переменные окружения | Переменная | Обязательна | Назначение | @@ -37,29 +62,3 @@ docker build -f runner/Dockerfile -t agent-news:dev . | `NEWS_PROMPT` | нет | промпт по умолчанию для `/news` без темы | | `CLAUDE_TIMEOUT_SECONDS` | нет | таймаут на ресёрч (по умолчанию 360) | | `MCP_CONFIG_PATH` | нет | путь к `mcp.json` (по умолчанию `/home/agent/claude-config/mcp.json`) | - -## Первичная авторизация Claude Code - -Claude Code CLI использует OAuth-логин через Claude.ai (подписка, не API-ключ). После -первого деплоя нужно один раз пройти логин внутри пода — иначе `claude -p ...` будет -падать с ошибкой авторизации: - -```bash -kubectl exec -it -n platformteam deploy/agent-news -- claude -``` - -CLI напечатает ссылку — открой её в браузере, авторизуйся. Токен сохранится в -`~/.claude` (persist через PVC `agent-news-home`, см. `deploy/agent-news`), так что -после рестарта пода логин не слетит. - -## Деплой - -Стандартный BearsDev CI/CD (см. `bearsdev-systems/ai-agents/knowledge/cicd.md`): -`git push` → `.gitea/workflows/build.yaml` собирает и пушит образ → бампит тег в -`deploy/agent-news` → `.gitea/workflows/deploy.yaml` применяет манифест в K3s. - -Перед первым деплоем вручную (см. план и `cicd.md`): -1. Создать `deploy/agent-news` репо с `deployment.yaml` + `.gitea/workflows/deploy.yaml`. -2. `kubectl apply -f pvc.yaml` — PVC `agent-news-home`, один раз, не через CI. -3. `kubectl create secret generic agent-news-secrets -n platformteam --from-literal=TELEGRAM_BOT_TOKEN=... --from-literal=ALLOWED_CHAT_IDS=...` -4. После первого деплоя — авторизация Claude Code (см. выше). diff --git a/bot/lib/claude_runner.dart b/bot/lib/claude_runner.dart index 34a3261..4b841e7 100644 --- a/bot/lib/claude_runner.dart +++ b/bot/lib/claude_runner.dart @@ -41,6 +41,7 @@ class ClaudeRunner { prompt, '--mcp-config', config.mcpConfigPath, + '--strict-mcp-config', '--dangerously-skip-permissions', ], environment: {'TELEGRAM_BOT_TOKEN': config.telegramToken}, diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6ab679e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +services: + agent-news: + build: + context: . + dockerfile: runner/Dockerfile + env_file: .env + volumes: + - claude-home:/home/agent/.claude + restart: unless-stopped + +volumes: + claude-home: