opencode-config/README.md
Sergey eb5697e28f
docs(readme): bilingual cleanup with minimalism and fix stale command (#89)
* docs(readme): rewrite with bilingual structure and minimalism

* docs(handoff): add handoff + ADR for README cleanup

* docs(handoff): set PR number

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-26 23:05:29 +03:00

247 lines
No EOL
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# opencode-config
Personal opencode setup — Docker-based AI coding assistant with persistent memory plugin and pipeline automation.
## Russian
### Quick start
```bash
git clone https://github.com/slaid098/opencode-config.git
cd opencode-config
cp .env.example .env # заполнить ключи (см. Configuration)
docker compose up -d
```
Доступ: http://localhost:4096. Память инициализируется автоматически при первом старте контейнера.
### Structure
| Путь | Описание |
|------|----------|
| `AGENTS.md` | Глобальные правила оркестратора (главный агент = только план) |
| `.opencode/` | Конфигурация проекта (auto-discovered, без env var) |
| `.opencode/agents/` | Subagent definitions (docs-reviewer, memory-syncer, reviewer) |
| `.opencode/skills/` | Skill definitions (14 skills) |
| `.opencode/scripts/` | Python scripts (pipeline-status, spec-status) |
| `src/` | Python RAG CLI (memory) |
| `docs/` | Handoffs, ADRs, project map |
### Configuration
Скопируйте `.env.example``.env` и заполните. Не-memory переменные:
| Variable | Default | Description |
|----------|---------|-------------|
| `AI_PROVIDER_BASE_URL` | — (required) | URL API AI-провайдера |
| `AI_PROVIDER_API_KEY` | — (required) | Ключ API AI-провайдера |
| `OPENCODE_SERVER_PASSWORD` | — (required) | Пароль сервера opencode |
| `GITHUB_TOKEN` | — (required) | GitHub personal access token |
| `CONTEXT7_API_KEY` | — (optional) | Context7 MCP API key |
| `ANTIDETECT_BROWSER_MCP_URL` | `http://localhost:8765/mcp` | Antidetect browser MCP URL (optional) |
Memory-переменные — в секции [Memory setup → Environment variables](#environment-variables-1).
### Memory setup
Плагин `@mathew-cf/opencode-memory` — гибридный поиск: ripgrep (keyword) + cloud embeddings (OpenRouter Qwen3 8B, 4096 dim, $0.01/M tokens).
#### How it works
```
opencode (plugin) → rag.js wrapper → python3 -m src.memory → OpenRouter API
↘ ripgrep (keyword search, parallel)
```
`memory_search` параллельно: ripgrep + embeddings, merge по score. `memory_save` коммитит + auto-push + incremental reindex (~1 sec). Первый full reindex: ~4 min для 78 файлов.
#### Prerequisites
1. Fork [`slaid098/opencode-memory`](https://github.com/slaid098/opencode-memory) → ваш GitHub
2. OpenRouter API key ([openrouter.ai](https://openrouter.ai), Qwen3 8B = $0.01/M tokens)
3. Заполнить `.env` (см. Configuration + Environment variables ниже)
#### Initialize
Docker (рекомендуется): `docker compose up -d` — авто-инициализация через `memory-setup` tool.
Повтор вручную:
```bash
docker exec opencode /root/.config/opencode/scripts/setup-memory.sh
```
Bare metal: `uv sync && .opencode/scripts/setup-memory.sh`.
#### setup-memory.sh steps
Скрипт идемпотентный (безопасно перезапускать):
1. Create `OPENCODE_MEMORY_DIR` if missing
2. Clone memory repo (or `pull --ff-only` if exists)
3. Verify remote origin matches `OPENCODE_MEMORY_REMOTE`
4. Install post-commit hook (auto-push on `memory_save`)
5. Build RAG index if `.rag/index.json` missing (full reindex, ~4 min)
6. Generate JS wrapper at `rag.js` (delegates to Python CLI; original backed up to `.orig`)
#### Verify
```bash
cat node_modules/@mathew-cf/rag-cli/bin/rag.js # Python shim ~10 lines, not Rust binary (71)
cat $OPENCODE_MEMORY_DIR/.rag/meta.json | python3 -m json.tool | head -5 # version + sha256
ls -la $OPENCODE_MEMORY_DIR/.rag/ # index.json + meta.json + .lock (no index.bin)
```
```bash
node node_modules/@mathew-cf/rag-cli/bin/rag.js search "docker compose bind mount" \
-i $OPENCODE_MEMORY_DIR/.rag -k 3 --json
```
#### Troubleshooting
| Симптом | Причина | Fix |
|---------|---------|-----|
| `Semantic search is unavailable` | Wrapper не сгенерирован / rag-cli не установлен | Re-run `setup-memory.sh` |
| Результаты без scores | Rust rag-cli (old wrapper) | Проверить `rag.js` = Python shim; re-run `setup-memory.sh` |
| `Index version mismatch` при каждом запуске | meta.json missing/stale | `rm -rf $OPENCODE_MEMORY_DIR/.rag/` + re-run |
| `OPENAI_BASE_URL env var not set` | `.env` не загружен | Docker: `docker compose up -d --force-recreate`; bare: `.env` в CWD |
| 429 rate limit от OpenRouter | Batch too large / too fast | Уменьшить `OPENAI_EMBEDDING_BATCH_SIZE` (default 50, max 100) |
| Stale Rust artifacts (`index.bin`) | Миграция со старого rag-cli | `rm -rf $OPENCODE_MEMORY_DIR/.rag/` + re-run `setup-memory.sh` |
#### Environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| `OPENCODE_MEMORY_DIR` | `/root/.local/share/opencode/opencode-memory` | Расположение memory repo |
| `OPENCODE_MEMORY_REMOTE` | — (required) | Git remote для вашего fork opencode-memory |
| `OPENAI_BASE_URL` | — (required) | URL embeddings API (OpenRouter: `https://openrouter.ai/api/v1`) |
| `OPENAI_API_KEY` | — (required) | OpenRouter API key |
| `OPENAI_EMBEDDING_MODEL` | `qwen/qwen3-embedding-8b` | Embedding model (4096 dim) |
| `OPENAI_EMBEDDING_BATCH_SIZE` | `50` | Chunks per API call (OpenRouter max 100) |
| `MEMORY_CHUNK_SIZE` | `512` | Размер chunk в символах |
| `MEMORY_CHUNK_OVERLAP` | `64` | Overlap между chunks |
| `MEMORY_WRAPPER_PATH` | (auto) | Override rag.js wrapper path (for tests) |
| `MEMORY_WRAPPER_PYTHON` | (auto) | Override Python binary для wrapper (for tests) |
## English
### Quick start
```bash
git clone https://github.com/slaid098/opencode-config.git
cd opencode-config
cp .env.example .env # fill in keys (see Configuration)
docker compose up -d
```
Access at http://localhost:4096. Memory initializes automatically on first container start.
### Structure
| Path | Description |
|------|-------------|
| `AGENTS.md` | Global orchestrator rules (main agent = plan only) |
| `.opencode/` | Project-local config (auto-discovered, zero env var) |
| `.opencode/agents/` | Subagent definitions (docs-reviewer, memory-syncer, reviewer) |
| `.opencode/skills/` | Skill definitions (14 skills) |
| `.opencode/scripts/` | Python scripts (pipeline-status, spec-status) |
| `src/` | Python RAG CLI (memory) |
| `docs/` | Handoffs, ADRs, project map |
### Configuration
Copy `.env.example``.env` and fill in. Non-memory variables:
| Variable | Default | Description |
|----------|---------|-------------|
| `AI_PROVIDER_BASE_URL` | — (required) | AI provider API URL |
| `AI_PROVIDER_API_KEY` | — (required) | AI provider API key |
| `OPENCODE_SERVER_PASSWORD` | — (required) | opencode server password |
| `GITHUB_TOKEN` | — (required) | GitHub personal access token |
| `CONTEXT7_API_KEY` | — (optional) | Context7 MCP API key |
| `ANTIDETECT_BROWSER_MCP_URL` | `http://localhost:8765/mcp` | Antidetect browser MCP URL (optional) |
Memory variables — see [Memory setup → Environment variables](#environment-variables-1) section.
### Memory setup
Plugin `@mathew-cf/opencode-memory` — hybrid search: ripgrep (keyword) + cloud embeddings (OpenRouter Qwen3 8B, 4096 dim, $0.01/M tokens).
#### How it works
```
opencode (plugin) → rag.js wrapper → python3 -m src.memory → OpenRouter API
↘ ripgrep (keyword search, parallel)
```
`memory_search` runs both paths in parallel, merges by score. `memory_save` commits + auto-pushes + incremental reindex (~1 sec). First full reindex: ~4 min for 78 files.
#### Prerequisites
1. Fork [`slaid098/opencode-memory`](https://github.com/slaid098/opencode-memory) to your GitHub
2. OpenRouter API key ([openrouter.ai](https://openrouter.ai), Qwen3 8B = $0.01/M tokens)
3. Fill `.env` (see Configuration + Environment variables below)
#### Initialize
Docker (recommended): `docker compose up -d` — auto-init via `memory-setup` tool.
Re-run manually:
```bash
docker exec opencode /root/.config/opencode/scripts/setup-memory.sh
```
Bare metal: `uv sync && .opencode/scripts/setup-memory.sh`.
#### setup-memory.sh steps
Script is idempotent — safe to re-run:
1. Create `OPENCODE_MEMORY_DIR` if missing
2. Clone memory repo (or `pull --ff-only` if exists)
3. Verify remote origin matches `OPENCODE_MEMORY_REMOTE`
4. Install post-commit hook (auto-push on `memory_save`)
5. Build RAG index if `.rag/index.json` missing (full reindex, ~4 min)
6. Generate JS wrapper at `rag.js` (delegates to Python CLI; original backed up to `.orig`)
#### Verify
```bash
cat node_modules/@mathew-cf/rag-cli/bin/rag.js # Python shim ~10 lines, not Rust binary (71)
cat $OPENCODE_MEMORY_DIR/.rag/meta.json | python3 -m json.tool | head -5 # version + sha256
ls -la $OPENCODE_MEMORY_DIR/.rag/ # index.json + meta.json + .lock (no index.bin)
```
```bash
node node_modules/@mathew-cf/rag-cli/bin/rag.js search "docker compose bind mount" \
-i $OPENCODE_MEMORY_DIR/.rag -k 3 --json
```
#### Troubleshooting
| Symptom | Cause | Fix |
|---------|-------|-----|
| `Semantic search is unavailable` | Wrapper not generated / rag-cli not installed | Re-run `setup-memory.sh` |
| Results without scores | Rust rag-cli (old wrapper) | Check `rag.js` is Python shim; re-run `setup-memory.sh` |
| `Index version mismatch` on every run | meta.json missing/stale | `rm -rf $OPENCODE_MEMORY_DIR/.rag/` + re-run |
| `OPENAI_BASE_URL env var not set` | `.env` not loaded | Docker: `docker compose up -d --force-recreate`; bare: `.env` in CWD |
| 429 rate limit from OpenRouter | Batch too large / too fast | Reduce `OPENAI_EMBEDDING_BATCH_SIZE` (default 50, max 100) |
| Stale Rust artifacts (`index.bin`) | Migrating from old rag-cli | `rm -rf $OPENCODE_MEMORY_DIR/.rag/` + re-run `setup-memory.sh` |
#### Environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| `OPENCODE_MEMORY_DIR` | `/root/.local/share/opencode/opencode-memory` | Memory repo location |
| `OPENCODE_MEMORY_REMOTE` | — (required) | Git remote for your opencode-memory fork |
| `OPENAI_BASE_URL` | — (required) | Embeddings API URL (OpenRouter: `https://openrouter.ai/api/v1`) |
| `OPENAI_API_KEY` | — (required) | OpenRouter API key |
| `OPENAI_EMBEDDING_MODEL` | `qwen/qwen3-embedding-8b` | Embedding model (4096 dim) |
| `OPENAI_EMBEDDING_BATCH_SIZE` | `50` | Chunks per API call (OpenRouter max 100) |
| `MEMORY_CHUNK_SIZE` | `512` | Chunk size in characters |
| `MEMORY_CHUNK_OVERLAP` | `64` | Overlap between chunks |
| `MEMORY_WRAPPER_PATH` | (auto) | Override rag.js wrapper path (for tests) |
| `MEMORY_WRAPPER_PYTHON` | (auto) | Override Python binary for wrapper (for tests) |
## License
MIT — see [LICENSE](LICENSE).