* 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>
247 lines
No EOL
11 KiB
Markdown
247 lines
No EOL
11 KiB
Markdown
# 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). |