OPENCODE_CONFIG_DIR в opencode v1.18.18 перенаправляет Global.Path.config
(global.ts: config = OPENCODE_CONFIG_DIR ?? ~/.config/opencode), из-за чего
глобальный конфиг (модель/провайдеры, напр. tokentool) не загружался и
opencode уходил в fallback-модель. Агенты открывались, т.к. OPENCODE_CONFIG_DIR
дополнительно сканируется как каталог для agent/*.md.
Теперь агенты распаковываются в <worktree>/.opencode/agent/*.md, где opencode
находит их через project-каталог .opencode (paths.ts, cwd=worktree). Глобальный
конфиг не трогаем вовсе.
- internal/opencode: удалены Server.ConfigDir/Pool.ConfigDir и env OPENCODE_CONFIG_DIR
- internal/config: удалено поле OpenCodeCfg.ConfigDir (config_dir)
- internal/app: ensureAgentsDir пишет в <worktree>/.opencode/agent
- internal/agents: WriteTo(dir) → dir/agent/*.md
- README/config.yaml.example/memory обновлены
- TelegramCfg.Enabled (дефолт true); при false канал не создаётся и не крепится в Router, long-poll не стартует — нет сетевых вызовов к api.telegram.org
- Validate требует token/chat_id только при enabled
- Load пресетит enabled=true до unmarshal (applyDefaults для bool не различает явный false)
- тесты, README и config.yaml.example обновлены
- CreateSession(ctx, agent) шлёт {agent} в POST /api/session, модель не выбираем
- удалён internal/opencode/config.go (ReadModelRef/JSONC-стрип) и его тесты
- runner.go больше не читает конфиг opencode и не хардпинит модель
- тесты и README обновлены
- chat.Router: ограниченный пул chatWorkers=4 воркеров + FIFO-очереди
per-user (userState/workerLoop/runUser). Порядок сообщений одного UserID
сохраняется; разные пользователи обрабатываются параллельно (до 4
одновременных LLM-вызовов), long-poll Telegram не блокируется чужим
аналитиком. Backpressure по jobs — только на перегруженного пользователя.
- app.FreeChat: sessions под sync.Mutex (защита от data race при параллельных
воркерах роутера).
- update: ResolveLatest проверяет наличие бинаря HEAD-пробой без скачивания
тела (fallback GET Range 0-0 при 405/501), сортировка версий по id убыв.;
один общий http.Client (keep-alive) вместо нового на каждый запрос.
- тесты: порядок/параллелизм per-user в router, HEAD-без-тела и фоллбэк на
версию без бинаря в update.
- память Serena: инварианты Router/update, примечания по форматированию на Windows.
Сохраняем онбоардинг-память проекта (core, tech_stack, conventions,
suggested_commands, task_completion) в .serena и коммитим служебную
директорию, чтобы она была доступна на сервере. Директория НЕ исключена
в .gitignore (локально исключаются только cache и project.local.yml).