Document current coding-workflow stack state

Snapshot of where opencode + Qwen3-Coder + MCPs + Kimi-Linear + voice
  + Phoenix tracing land today, plus in-flight (oc-tree, kimi-linear
  context ramp) and next (ComfyUI) items with pointers to per-project
  NEXT_STEPS.md guides.
This commit is contained in:
2026-05-10 21:14:43 -04:00
parent 228fe8d1ac
commit a29793032d
35 changed files with 2067 additions and 37 deletions

View File

@@ -5,14 +5,61 @@ stack. `install.sh` deploys it to `~/.config/opencode/` on a Mac.
## What's wired up
- **Local model**: `framework/qwen3-coder:30b` served by Ollama on the
Framework Desktop, reachable over Tailscale.
- **Local models**: two providers, manually switched via `/model`.
- `framework/qwen3-coder:30b` — Qwen3-Coder 30B-A3B via Ollama, the
daily-driver coding model. 128K context, 11434.
- `framework-vllm/kimi-linear` — Kimi-Linear 48B-A3B via vLLM, the
long-context play (hybrid KDA/MLA, MoE 3B active). 32K context for
now (ramps further in P3 of the kimi-linear roadmap), 8000.
**Tools disabled** (`tool_call: false`) — Kimi-Linear is a research
architecture release and isn't strongly tool-trained; the model
knows the Kimi-K2 tool tokens but emits non-structured output when
given an MCP toolbox. Use it for chat / long-context reasoning;
switch to `framework/qwen3-coder:30b` for agentic work.
- **Playwright MCP** ([@playwright/mcp](https://github.com/microsoft/playwright-mcp)) —
browser automation. The model can navigate pages, click, fill forms,
read DOM snapshots. Closes the agentic-browsing gap.
- **SearXNG MCP** ([mcp-searxng](https://github.com/ihor-sokoliuk/mcp-searxng)) —
web search via your self-hosted instance at <https://searxng.n0n.io>.
No external API keys, no rate-limit roulette.
- **Serena MCP** ([oraios/serena](https://github.com/oraios/serena)) —
LSP-backed semantic code navigation (find symbol, references, rename,
insert before/after). Cuts the tokens a local 70B-class model burns on
grep-style flailing by roughly an order of magnitude. Uses a **custom
trimmed context** (`serena-ide-trim.yml`) that exposes only the 8
unique-LSP-value tools — JetBrains tools, line-level edits redundant
with opencode's `Edit`, Serena's own memory tools (basic-memory MCP is
canonical), and onboarding/meta noise are all excluded. Down from 46
raw → 41 ide-context-filtered → **8 active**. Scoped to the cwd via
`--project-from-cwd`.
- **basic-memory MCP** ([basicmachines-co/basic-memory](https://github.com/basicmachines-co/basic-memory)) —
Markdown-backed persistent memory across sessions. Storage lives in
`~/Documents/obsidian/AI-memory/` (symlinked from `~/basic-memory`),
so notes are browsable in Obsidian's graph and search. Replaces
Claude Code's auto-memory write-back, which opencode lacks natively.
- **sequential-thinking MCP** ([modelcontextprotocol/servers/sequentialthinking](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking)) —
externalizes chain-of-thought as tool calls. Helps weaker local
models stay on-plan over multi-step work; near-zero cost when not
actively used.
- **github MCP** ([github/github-mcp-server](https://github.com/github/github-mcp-server)) —
GitHub repo / issue / PR / code-search access. Launched with
`--read-only` and a narrowed `--toolsets repos,issues,pull_requests,code_security`
allowlist. With a **classic** PAT (`ghp_…`), GitHub's auto-scope-filtering
(Jan 2026) trims tools further by hiding ones whose scopes the token
lacks — saves ~23k tokens of tool-list overhead, meaningful for a 70B's
effective context. Requires `GITHUB_PERSONAL_ACCESS_TOKEN` to be exported
in your shell env (not in opencode.json). Drop `--read-only` from
`opencode.json` once you trust the model's tool calls.
**Note**: This MCP is disabled since the user is utilizing a self-hosted Gitea instance instead of GitHub.
- **task-master MCP** ([eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master)) —
Workflow / task-gate MCP. File-based: each project gets a
`.taskmaster/` dir with tasks, complexity, and config — no DB, no
external service. `OLLAMA_BASE_URL` is pre-set in `opencode.json` so
task-master's AI features (parse-prd, expand-task) route through your
framework Ollama. The npm-global install also provides a `task-master`
CLI (`task-master init` to scaffold per-project). Replaces the
workflow-gate role originally proposed for Archon, without Supabase.
- **Phoenix bridge plugin** (`.opencode/plugin/phoenix-bridge.js`) —
exports OpenTelemetry spans for every LLM call, tool call, and
subagent invocation to the Phoenix container running on the Framework
@@ -31,13 +78,22 @@ the plugin. Each step checks before doing work. Specifically:
1. Verifies Homebrew is present (won't install it for you)
2. `brew install node uv jq sst/tap/opencode` (skips if already at latest)
3. Pre-caches Playwright's chromium so the first MCP call is instant
4. `npm install` in `.opencode/plugin/` for the Phoenix bridge OTel deps
5. Generates `~/.config/opencode/opencode.json` from the repo's
4. `uv tool install serena-agent@latest --prerelease=allow` so opencode
can launch Serena as a plain `serena` binary on PATH (faster than
re-resolving via `uvx` on every session)
5. Creates `~/Documents/obsidian/AI-memory/` and symlinks `~/basic-memory`
to it, so basic-memory MCP writes into the Obsidian vault by default
6. `brew install github-mcp-server` and warns if `GITHUB_PERSONAL_ACCESS_TOKEN`
isn't set in your shell — the MCP needs it to authenticate
7. `npm install -g task-master-ai` (workflow MCP, also exposes the
`task-master` CLI for `task-master init` per project)
8. `npm install` in `.opencode/plugin/` for the Phoenix bridge OTel deps
9. Generates `~/.config/opencode/opencode.json` from the repo's
`opencode.json`, rewriting relative plugin paths to absolute so
OpenCode loads the plugin regardless of which directory it's launched
from
Step 5 is the reason the deployed config isn't a plain symlink. The
Step 9 is the reason the deployed config isn't a plain symlink. The
repo's `opencode.json` uses a relative plugin path (`./...`) so it stays
valid in place; the deployed copy is generated with that path resolved
to an absolute one. Edits to the repo's `opencode.json` need a re-run
@@ -57,11 +113,35 @@ Then in opencode:
```
opencode
> /mcp # should list playwright and searxng as connected
> /mcp # should list playwright, searxng, serena, basic-memory,
# sequential-thinking, github, task-master as connected
> search the web for "qwen3-coder benchmarks"
> open https://example.com and tell me the H1
> use serena to find the definition of `parse_request`
> remember: this project ships its memory into the Obsidian vault
> /sequentialthinking think through the trade-offs of X vs Y
> list my recent github PRs across all repos
> task-master init # then ask the model to plan tasks for this project
```
For parallel agents, plain tmux + git worktree is enough at the 70B's
~2-pane concurrency ceiling. A two-line zsh helper covers the
"new isolated worktree → split tmux pane → start opencode" loop:
```sh
work() {
local name="${1:?usage: work <branch-name>}"
local wt="../$(basename "$PWD")-$name"
git worktree add "$wt" -b "$name" && tmux split-window -h -c "$wt" "opencode"
}
unwork() { local wt="$PWD"; cd .. && git worktree remove --force "$wt"; }
```
Serena's first invocation in a project may take a few seconds — it
indexes the workspace via the language server. basic-memory's first
write creates the project layout under `~/Documents/obsidian/AI-memory/`
which Obsidian will pick up on its next vault scan.
## Phoenix tracing
The plugin at `.opencode/plugin/phoenix-bridge.js` boots an OpenTelemetry
@@ -142,3 +222,32 @@ plugin no-ops — the rest of OpenCode still works fine.
using the same `type/command/enabled` shape. The
[official MCP registry](https://registry.modelcontextprotocol.io/)
and [Awesome MCP Servers](https://mcpservers.org/) catalog options.
- **Tool-list bloat is real on a local 70B.** Every tool description
costs context. Five MCP servers exposing ~10 tools each puts the
active-tool list around 50 — manageable, but adding two more
full-spectrum servers (e.g. GitHub MCP at ~70 tools without scope
filtering, plus Context7) starts crowding effective context. Prefer
servers with toolset filtering or per-agent allow-lists in opencode.
- **basic-memory storage path.** The symlink `~/basic-memory`
`~/Documents/obsidian/AI-memory` is created by `install.sh` only if
`~/basic-memory` doesn't already exist. If you'd previously run
basic-memory before this setup, move that directory's contents into
`AI-memory/` first, then delete `~/basic-memory` and re-run
`install.sh`.
- **Serena PATH gotcha.** `uv tool install` puts `serena` in
`~/.local/bin/`. If your shell rc doesn't export that, `opencode`
won't find the binary. The script warns; fix is one line in
`~/.zshrc`: `export PATH="$HOME/.local/bin:$PATH"`.
- **Serena tool trim** (`serena-ide-trim.yml`). The custom context
excludes 28 tools beyond what the built-in `ide` context already
filters. To re-expose any of them, edit
[`serena-ide-trim.yml`](serena-ide-trim.yml) and remove the entry
from `excluded_tools`, then re-run `./install.sh`. The path injection
(`./serena-ide-trim.yml` → absolute) is handled by install.sh's jq
pass at deploy time.
- **GitHub PAT.** Use a **classic** PAT (`ghp_…`) — auto-scope-filtering
only kicks in for classic tokens, not fine-grained ones. Without
it, the GitHub MCP exposes its full ~70-tool surface, which costs
~23k tokens of context the local 70B can ill afford. Generate at
<https://github.com/settings/tokens> with the scopes you actually
want exposed.