diff --git a/.serena/.gitignore b/.serena/.gitignore new file mode 100644 index 0000000..2e510af --- /dev/null +++ b/.serena/.gitignore @@ -0,0 +1,2 @@ +/cache +/project.local.yml diff --git a/.serena/memories/conventions.md b/.serena/memories/conventions.md new file mode 100644 index 0000000..1e7d79e --- /dev/null +++ b/.serena/memories/conventions.md @@ -0,0 +1,39 @@ +# conventions + +## Стиль / кодстайл +- Стандартный Go-стиль; гофм `gofmt`/`go fmt ./...`. Документация-комментарии и + package-doc на русском языке (в START-комментариях файлов и doc-комментариях). +- Типизация: строгие типы, интерфейсы для абстракций (Decider, LiveProber). +- Свой тип `config.Duration` для времени (YAML-строки "5s"/"10m"), метод `.Duration()`. + +## Обработка ошибок +- Ошибки классифицируются по идентификаторам классов в исходниках (см. ниже). +- Ошибка-обёртка: `fmt.Errorf("%w: %v", ErrXxx, err)`. +- `errors.Join` для склейки нескольких ошибок валидации (config.Validate). + +## Классы ошибок (маркируются в коде, документированы в README) +| Блок | Коды | Где | +|---|---|---| +| C | C1–C4 | internal/config | +| A | A1–A4 | internal/analyst | +| M | M1–M5 | internal/chat | +| O | O1–O4 | internal/opencode | +| S | S1–S5 | internal/storage | +| W | W1–W5 | internal/worker | +| E | E1–E4 | internal/worker (репозитории) | +| R | R1–R6 | internal/worker/review_errors.go | +| U | U1–U6 | internal/update | + +## Архитектурные конвенции +- **Composition root** — internal/app; подсистемы собираются там, лимиты Core + (MaxTurns=15, MaxConfirmCycles=3, MaxQuestionsPerTurn=5) в core.New. +- **Агенты** (analyst.md/dev.md/reviewer.md) — markdown-промпты, встроены через go:embed + (internal/agents/*.md + embed.go), распаковываются в config_dir. Вердикт — строгий JSON. +- Репо-клонирование/воркеры — через gitops; ветки задач `feat/` (см. mem:core). +- Обратная совместимость: поле `Repo` (одиночный) и `Repos` (список); EffectiveRepos/ + SetReposFromDB/ReposJoined в storage/models.go. + +## Версии +- `app.Version` — семантическая major.minor.patch (ручной инкремент: patch=фиксы, + minor=новая обратно-совместимая функциональность, major=несовместимые изменения). +- `main.version` (ldflag) — build-идентификатор `commit-`, отдельно от app.Version. \ No newline at end of file diff --git a/.serena/memories/core.md b/.serena/memories/core.md new file mode 100644 index 0000000..6ae8029 --- /dev/null +++ b/.serena/memories/core.md @@ -0,0 +1,51 @@ +# core + +Ratatoskr-go — оркестратор конвейера Ratatoskr (порт с Python на Go) в единый +статический бинарь (CGO_ENABLED=0). Субагенты запускаются через внешний процесс +[opencode](https://opencode.ai). Взаимодействие — Telegram-бот. + +## Структура (модули internal/) + +``` +cmd/ratatoskr/ точка входа, сборка бинаря; main.version и main.updateToken вшиваются ldflag'ом +internal/ + app/ composition root/DI: App.New -> config.Load+Validate, ResolveExePaths, storage, Runner, Analyst, Core, Worker, Updater. packageOwner="kamelion", Version="0.1.0" + config/ YAML+env загрузка (${VAR:-default}), defaults, validate C1-C4 + chat/ мультиканальный Router; telegram — long-poll канал. Коды M1-M5 + core/ state-machine задач + Decider/analyst интерфейс. Коды D3/D4 + analyst/ аналитик: промпт + разбор JSON-вердикта (opencode agent). Коды A1-A4 + worker/ polling-планировщик + dev/reviewer-конвейер + gitops. Коды W*, E*, R* + agents/ встроенные opencode-агенты (analyst.md, dev.md, reviewer.md) через go:embed + opencode/ обёртка запуска opencode, LiveRegistry, парсинг вердикта. Коды O1-O4 + storage/ SQLite (modernc.org/sqlite, без CGO): tasks, traces, task_history. Коды S1-S5 + update/ автообновление из Gitea Packages. Коды U1-U6 +``` + +## Ключевые инварианты + +- **Команды/ядро:** Core.ProcessTurn — state-machine поверх storage. Команды: + /start /cancel /skip /retry N /status N /continue N. Активная задача — одна на чат. +- **Фазы аналитика (Decision.Phase):** `ask` (уточняющие вопросы), `propose` (правки + черновика), `ready` (черновик полон как есть), `abort` (тема вне проекта). propose и ready + в core обрабатываются одинаково. +- **Статусы задач:** draft→collecting→ready→approved→running→success/failed/timeout, + плюс cancelled/aborted/closed. approved — финальное одобрение («создавай»), после чего + воркер берёт задачу. IsValidTransition/IsTerminal в storage/models.go. +- **Decider/Worker/Analyst/Reviewer:** Decider=analyst интерфейс (analyst пакет реализует); + Worker — polling-планировщик dev-агента; Reviewer проверяет diff dev-ветки (R1-R6), + вердикт JSON {passed, critical_issues, solid_violations, comments}. +- **gitops (worker):** worker работает с worktrees; feature-ветка = `feat/` от + origin/main; ensureBranch (reset --hard + clean -fd + checkout -B), branchDiff + (`origin/main...`), push через http.extraHeader, токен как Bearer. +- **Пути «всё рядом с .exe»:** относительные db/worktree резолвятся от каталога бинаря + (ExeDir), не от cwd. config.yaml ищутся рядом с бинарём, фоллбэк cwd. +- **Автообновление:** авто = только Check+уведомление; замена — по /update. Версии в + Gitea Packages `commit-/` (не `latest/`). Вердикты агентов — строгий JSON. + +## Контракты (не ломать) + +- `App.New(configPath, version, updateToken string)` — сигнатура. +- `packageOwner` — константа "kamelion" (не плодить vars/ldflag/конфиг). +- `update.Updater` — создаётся структурой `&update.Updater{...}`, конструктора нет. + +См. также `mem:tech_stack`, `mem:conventions`, `mem:task_completion`, `mem:suggested_commands`. \ No newline at end of file diff --git a/.serena/memories/memory_maintenance.md b/.serena/memories/memory_maintenance.md new file mode 100644 index 0000000..6f84514 --- /dev/null +++ b/.serena/memories/memory_maintenance.md @@ -0,0 +1,33 @@ +# Memory Maintenance + +## Discovery Model + +- Core principle: progressive discovery through references, building a graph of memories. +- Initially, agents are provided with the list of all memories (names only). +- Agents should read `mem:core` as the top-level entry point (graph root). + This memory should contain references to other memories covering major project domains. + The referenced memories shall, in turn, shall contain references to even more specific memories, and so on. + The depth of the graph shall depend on the project complexity. +- Use topics/folders to group related memories in order to make the content structure explicit. + Folders can mirror project structure (e.g. modules like frontend/backend) or topics like debugging, architecture, etc. +- Memory references must use a mem: prefix inside backticks, e.g. `mem:frontend/core`. + The surrounding text should clearly indicate when to read the memory/which content to expect. + The text should provide more precise guidance than the memory name alone, + i.e. avoid a reference like "frontend debugging: `mem:frontend/debugging` and instead make clear which aspects of frontend debugging are covered. +- Memories themselves should not contain information about when to read them; this is the responsibility of the referring memory. + +## Style + +Dense agent notes, not prose docs. Prefer invariants, terse bullets. +Avoid obvious context, rationale, and examples unless they prevent likely mistakes. +Keep guidance durable and generalizable, not task-local. + +## Add/update threshold + +Add or update memories only with stable, non-obvious project conventions that avoid complex rediscovery in the future. +Do not add: quick-read facts; generic language/framework knowledge; one-off task notes; volatile line-level details; behavior likely to change soon. + +## Maintenance Actions + +- Renaming memories: References are updated automatically if handled via Serena's memory rename tool. +- Checking for stale memories (e.g. after deletion): Call `serena memories check` for a report. \ No newline at end of file diff --git a/.serena/memories/suggested_commands.md b/.serena/memories/suggested_commands.md new file mode 100644 index 0000000..b00ffa5 --- /dev/null +++ b/.serena/memories/suggested_commands.md @@ -0,0 +1,27 @@ +# suggested_commands + +## Сборка / проверки (из корня репо) +- `go test ./... -v -count=1 -timeout 120s` (или `make test`) — все тесты. +- `go vet ./...` (или `make vet`). +- `go fmt ./...` (или `make fmt`). +- `go build -o ratatoskr ./cmd/ratatoskr/` (или `make build`). +- `./ratatoskr -config config.yaml` (или `make run`). +- `./ratatoskr -version` — показать версию бинаря. +- Кросс-сборка: `make cross` (linux/amd64 + windows/amd64). + +## Go-тулчейн +Хост без `go` в PATH — экспорт вручную: +``` +export PATH=/opt/data/.local/go/bin:$PATH +``` +На машине разработки (Windows, cmd) — обычный system Go. + +## git (worktree-процесс Ratatoskr) +- Feature-ветка: `feat/`, база — `origin/main`. Пример проверки diff всей ветки: + `git diff origin/main...HEAD`. +- Проверить состав отслеживаемых файлов (например наличие .serena): `git ls-files`. +- Статус: `git status`. Лог: `git log --oneline -10`. + +## Замечания про среду +- ОС Windows + PowerShell 5.1 (shell: powershell) — команды собирать/запускать с учётом + этом (нет `&&`; использовать `;`/`if ($?) {}`; & для путей с пробелами). \ No newline at end of file diff --git a/.serena/memories/task_completion.md b/.serena/memories/task_completion.md new file mode 100644 index 0000000..87d4220 --- /dev/null +++ b/.serena/memories/task_completion.md @@ -0,0 +1,15 @@ +# task_completion + +Считается, что задача по коду выполнена строго после: + +1. **Формат/линт:** `go fmt ./...` (без неотформатированных файлов). +2. **Тесты:** `go test ./... -v -count=1 -timeout 120s` — все проходят (`make test`). +3. **Статический анализ:** `go vet ./...` — чисто (`make vet`). +4. **Сборка:** `go build -o ratatoskr ./cmd/ratatoskr/` (`make build`) — компилируется. + (Кросс-сборка `make cross` — только при необходимости.) +5. **Пересмотр контрактов:** если менялась сигнатура `App.New(configPath, version, + updateToken string)` — обновить вызовы в `internal/app/app_test.go` (иначе go vet падает). +6. Коммит осмысленными атомарными коммитами в feature-ветку `feat/` от origin/main. + +Рабочий процесс Ratatoskr (агент dev в этом конвейере): изучить код, реализовать так, чтобы +все acceptance criteria были закрыты, закоммитить в ветку, вернуть отчёт. \ No newline at end of file diff --git a/.serena/memories/tech_stack.md b/.serena/memories/tech_stack.md new file mode 100644 index 0000000..ff27906 --- /dev/null +++ b/.serena/memories/tech_stack.md @@ -0,0 +1,30 @@ +# tech_stack + +## Язык / рантайм +- Go **1.25.0** (go.mod `go 1.25.0`). Модуль `github.com/kamelion/ratatoskr-go`. +- Сборка: статический бинарь, `CGO_ENABLED=0`. Локальный Go-тулчейн на хосте: + `export PATH=/opt/data/.local/go/bin:$PATH` (go1.25.0 linux/amd64). + +## Основные зависимости (go.mod) +- `gopkg.in/yaml.v3 v3.0.1` — парсинг config.yaml. +- `modernc.org/sqlite v1.56.0` — SQLite без CGO (чистый Go). +- (indirect) google/uuid, go-humanize, mattn/go-isatty, x/sys, modernc.org/libc/mathutil/memory. + +## Внешние процессы +- **opencode** (opencode.ai) — внешний процесс для субагентов (analyst/dev/reviewer). + Управляется через internal/opencode (Runner, LiveRegistry). Настраивается в конфиге + (opencode.bin / config / config_dir / hard_timeout / idle_timeout / poll_ms). + +## Сборка / Makefile +- `make build` — go build -ldflags="-s -w -X main.version=commit- -X main.updateToken=..." -o ratatoskr ./cmd/ratatoskr/. +- `make test` — go test ./... -v -count=1 -timeout 120s. +- `make vet` — go vet ./... `make fmt` — go fmt ./... +- `make run` — build + ./ratatoskr -config config.yaml. +- `make cross` — кросс-сборка linux/amd64 + windows/amd64 (ratatoskr-windows-amd64.exe — Windows-машина Камиля). +- GIT_SHA вшивается в main.version; UPDATE_TOKEN — в main.updateToken (секрет только у CI). + +## CI (.gitea/workflows/ci.yaml) +- Job `test`: go test ./... + go vet ./.... +- Job `build-and-package` (matrix linux/amd64+windows/amd64): собирает и публикует в + Gitea Packages на `main` в версию `commit-/` + companion-файлы `.version`/`.sha256`. +- Секреты: TC_GITEA_TOKEN (write:packages), TC_UPDATE_TOKEN (read:package), GIT_MAIN_URL. \ No newline at end of file diff --git a/.serena/project.yml b/.serena/project.yml new file mode 100644 index 0000000..fb466c8 --- /dev/null +++ b/.serena/project.yml @@ -0,0 +1,133 @@ +# the name by which the project can be referenced within Serena +project_name: "ratatoskr-go" + + +# list of languages for which language servers are started; choose from: +# al angular ansible bash clojure +# cpp cpp_ccls crystal csharp csharp_omnisharp +# dart elixir elm erlang fortran +# fsharp go groovy haskell haxe +# hlsl html java json julia +# kotlin lean4 lua luau markdown +# matlab msl nix ocaml pascal +# perl php php_phpactor powershell python +# python_jedi python_ty r rego ruby +# ruby_solargraph rust scala scss solidity +# svelte swift systemverilog terraform toml +# typescript typescript_vts vue yaml zig +# (This list may be outdated. For the current list, see values of Language enum here: +# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py +# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) +# Note: +# - For C, use cpp +# - For JavaScript, use typescript +# - For Angular projects, use angular (subsumes typescript+html; requires `npm install` in the project root) +# - For Svelte projects, use svelte (subsumes typescript/javascript for .svelte projects; requires npm) +# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three) +# - For Free Pascal/Lazarus, use pascal +# Special requirements: +# Some languages require additional setup/installations. +# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers +# When using multiple languages, the first language server that supports a given file will be used for that file. +# The first language is the default language and the respective language server will be used as a fallback. +# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. +languages: +- go + +# the encoding used by text files in the project +# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings +encoding: "utf-8" + +# line ending convention to use when writing source files. +# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default) +# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings. +line_ending: + +# The language backend to use for this project. +# If not set, the global setting from serena_config.yml is used. +# Valid values: LSP, JetBrains +# Note: the backend is fixed at startup. If a project with a different backend +# is activated post-init, an error will be returned. +language_backend: + +# whether to use project's .gitignore files to ignore files +ignore_all_files_in_gitignore: true + +# advanced configuration option allowing to configure language server-specific options. +# Maps the language key to the options. +# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available. +# No documentation on options means no options are available. +ls_specific_settings: {} + +# list of additional workspace folder paths for cross-package reference support (e.g. in monorepos). +# Paths can be absolute or relative to the project root. +# Each folder is registered as an LSP workspace folder, enabling language servers to discover +# symbols and references across package boundaries. +# Currently supported for: TypeScript. +# Example: +# additional_workspace_folders: +# - ../sibling-package +# - ../shared-lib +additional_workspace_folders: [] + +# list of additional paths to ignore in this project. +# Same syntax as gitignore, so you can use * and **. +# Note: global ignored_paths from serena_config.yml are also applied additively. +ignored_paths: [] + +# whether the project is in read-only mode +# If set to true, all editing tools will be disabled and attempts to use them will result in an error +# Added on 2025-04-18 +read_only: false + +# list of tool names to exclude. +# This extends the existing exclusions (e.g. from the global configuration) +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +excluded_tools: [] + +# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default). +# This extends the existing inclusions (e.g. from the global configuration). +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +included_optional_tools: [] + +# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools. +# This cannot be combined with non-empty excluded_tools or included_optional_tools. +# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html +fixed_tools: [] + +# list of mode names that are to be activated by default, overriding the setting in the global configuration. +# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes. +# If the setting is undefined/empty, the default_modes from the global configuration (serena_config.yml) apply. +# Otherwise, this overrides the setting from the global configuration (serena_config.yml). +# Therefore, you can set this to [] if you do not want the default modes defined in the global config to apply +# for this project. +# This setting can, in turn, be overridden by CLI parameters (--mode). +# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes +default_modes: + +# list of mode names to be activated additionally for this project, e.g. ["query-projects"] +# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes. +# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes +added_modes: + +# initial prompt for the project. It will always be given to the LLM upon activating the project +# (contrary to the memories, which are loaded on demand). +initial_prompt: "" + +# time budget (seconds) per tool call for the retrieval of additional symbol information +# such as docstrings or parameter information. +# This overrides the corresponding setting in the global configuration; see the documentation there. +# If null or missing, use the setting from the global configuration. +symbol_info_budget: + +# list of regex patterns which, when matched, mark a memory entry as read‑only. +# Extends the list from the global configuration, merging the two lists. +read_only_memory_patterns: [] + +# list of regex patterns for memories to completely ignore. +# Matching memories will not appear in list_memories or activate_project output +# and cannot be accessed via read_memory or write_memory. +# To access ignored memory files, use the read_file tool on the raw file path. +# Extends the list from the global configuration, merging the two lists. +# Example: ["_archive/.*", "_episodes/.*"] +ignored_memory_patterns: []