# 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).