From e6fdd6884dc531e5013e5c26360d0993048723f2 Mon Sep 17 00:00:00 2001 From: Lap Tran Date: Sun, 27 Sep 2026 21:30:11 -0400 Subject: [PATCH] chore: move agent routing to OpenCode Go; add firstmate tooling - crew-dispatch.json: route crew tasks to OpenCode Go models - opencode/opencode2: pin opencode-go/gpt-6-luna - grok: default to grok-4.5 with high reasoning, permission auto - home.nix: axiTools activation for the *-axi CLIs; crewmate harness opencode; no-mistakes agent list opencode-only --- home.nix | 79 +++++++++++++++++++---- home/.config/firstmate/crew-dispatch.json | 22 +++---- home/.config/opencode/opencode.json | 2 +- home/.config/opencode2/opencode.json | 2 +- home/.grok/config.toml | 7 +- 5 files changed, 84 insertions(+), 28 deletions(-) diff --git a/home.nix b/home.nix index 9ed53a4..07d357c 100644 --- a/home.nix +++ b/home.nix @@ -46,7 +46,7 @@ in cc = "claude --dangerously-skip-permissions"; co = "codex --full-auto"; gb = "grok --yolo"; - # firstmate primary session via OpenCode 2 (isolated config; crewmates = Pi) + # firstmate primary session via OpenCode 2 (isolated config; crewmates = OpenCode) fm = "cd ${firstmateHome} && exec ${home}/.local/bin/oc2"; oc2 = "${home}/.local/bin/oc2"; # Sync ~/Music into the beets library on Unraid (requires NAS mounted). @@ -170,10 +170,10 @@ in }; # firstmate is a mutable agent distro (self-update, state/, projects/). Clone once; - # never put it in the Nix store. Seed Pi+herdr defaults only when absent. + # never put it in the Nix store. Seed OpenCode+herdr defaults only when absent. # Do NOT npm install -g here: activation PATH often resolves Nix's npm, which - # cannot write into the store (EACCES). Use Homebrew's node for globals: - # /opt/homebrew/bin/npm install -g tasks-axi quota-axi no-mistakes gh-axi lavish-axi chrome-devtools-axi + # cannot write into the store (EACCES). The firstmate companion CLIs (*-axi) + # are installed by home.activation.axiTools below via Homebrew's node. home.activation.firstmate = lib.hm.dag.entryAfter [ "writeBoundary" ] '' set -euo pipefail fm="${firstmateHome}" @@ -188,11 +188,11 @@ in # Local gitignored operating choices (do not overwrite captain edits) [ -f "$fm/config/backend" ] || printf 'herdr\n' > "$fm/config/backend" - [ -f "$fm/config/crew-harness" ] || printf 'pi\n' > "$fm/config/crew-harness" + [ -f "$fm/config/crew-harness" ] || printf 'opencode\n' > "$fm/config/crew-harness" # Crew dispatch profile - source of truth in dotfiles (reproducible across # machines). Symlinked into firstmate config so a rebuild restores routing. - # Crewmates run on Pi + opencode-go/mimo-v2.5-pro (see crew-dispatch.json). + # Crew harness and model routing are task-specific in crew-dispatch.json. ln -sfn "${dotfiles}/home/.config/firstmate/crew-dispatch.json" "$fm/config/crew-dispatch.json" # Gitea PR helper for local-only mode: after the first mate (opencode) @@ -200,6 +200,33 @@ in ln -sfn "${dotfiles}/home/bin/fm-gitea-pr.sh" "$HOME/.local/bin/fm-gitea-pr.sh" ''; + # Firstmate companion CLIs (*-axi). None is a Homebrew or Nix formula, so + # install them through Homebrew's npm. tasks-axi is version-gated by firstmate + # (>= 0.2.6 is required before a spawn/teardown automatic backlog transition + # will run), so pin it and reinstall on drift; the rest install when absent. + home.activation.axiTools = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + set -euo pipefail + # Activation PATH lacks /opt/homebrew/bin, so npm's `#!/usr/bin/env node` + # shebang and the installed shims would fail. Prepend only - replacing PATH + # breaks the rest of the HM activation (nix-env, gettext). + export PATH="/opt/homebrew/bin:$PATH" + npm=/opt/homebrew/bin/npm + if [ ! -x "$npm" ]; then + echo "axiTools: /opt/homebrew/bin/npm missing (declare node in homebrew.brews)" >&2 + exit 1 + fi + # Pin tasks-axi; reinstall only when the installed version differs. + want_tasks_axi="0.2.6" + have_tasks_axi="$(tasks-axi --version 2>/dev/null | head -1 | tr -d '[:space:]')" + if [ "$have_tasks_axi" != "$want_tasks_axi" ]; then + "$npm" install -g "tasks-axi@$want_tasks_axi" + fi + # Companion CLIs without a firstmate-enforced version floor: install once. + for tool in quota-axi gh-axi lavish-axi chrome-devtools-axi; do + [ -x "/opt/homebrew/bin/$tool" ] || "$npm" install -g "$tool" + done + ''; + # Authorize the SSH key so the phone can log in through the ngrok tunnel. # (home-manager 26.05 removed programs.ssh.authorizedKeys; manage the file # here so ~/.ssh is 0700 and authorized_keys is 0600. Public key is not a secret.) @@ -236,9 +263,38 @@ in "$npm" install -g --allow-scripts=@opencode-ai/cli @opencode-ai/cli@beta ''; + # backpass (kunchenguid/backpass) - gradient descent for agent memory: reads + # the transcript stores of the harnesses this config already declares + # (claude/codex/pi/opencode/grok), proposes evidence-backed edits to AGENTS.md + # and skills, gated by `backpass apply`. Every model call goes through `acpx` + # to a harness you already authenticated, so acpx is a hard runtime dep and + # must be on PATH. Homebrew node v26 satisfies backpass (>= 22.5) and acpx + # (>= 22.13). Neither is a Homebrew formula: install via Homebrew's npm, + # never Nix's npm (EACCES on the store). Skip-if-present like opencode2 so a + # rebuild never pulls a new version mid-session; refresh manually with + # /opt/homebrew/bin/npm update -g backpass acpx + home.activation.backpass = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + set -euo pipefail + # Activation PATH lacks /opt/homebrew/bin, so npm's `#!/usr/bin/env node` + # shebang fails with "env: node: No such file or directory". Prepend only - + # replacing PATH breaks the rest of the HM activation (nix-env, gettext). + export PATH="/opt/homebrew/bin:$PATH" + npm=/opt/homebrew/bin/npm + if [ ! -x "$npm" ]; then + echo "backpass: /opt/homebrew/bin/npm missing (declare node in homebrew.brews)" >&2 + exit 1 + fi + if [ ! -x /opt/homebrew/bin/acpx ]; then + "$npm" install -g acpx@latest + fi + if [ ! -x /opt/homebrew/bin/backpass ]; then + "$npm" install -g backpass + fi + ''; + # kunchenguid/no-mistakes gate (git push no-mistakes) - declarative install + daemon + global config - # Covers every harness declared in Nix: pi (pi-coding-agent), opencode (oc2/fm), grok (grok-build), - # plus claude/codex aspirational (aliases cc/co). Binary lives in ~/.no-mistakes/bin + # Uses OpenCode only for pipeline steps (the opencode-go subscription), by the + # captain's decision. Binary lives in ~/.no-mistakes/bin # with symlink ~/.local/bin/no-mistakes (installer default). Do NOT npm install -g no-mistakes # - that npm name is jonathanong's static-analysis tool (shadowing bug fixed 2026-09-21). home.activation.noMistakes = lib.hm.dag.entryAfter [ "writeBoundary" ] '' @@ -252,14 +308,14 @@ in fi curl -fsSL https://raw.githubusercontent.com/kunchenguid/no-mistakes/main/docs/install.sh | sh fi - # Ensure global config covers all Nix harnesses (idempotent - only writes if missing or still `agent: auto`) + # Ensure global config selects OpenCode (idempotent - only writes if missing or still `agent: auto`) cfg="$HOME/.no-mistakes/config.yaml" if [ -f "$cfg" ] && grep -qE '^\s*agent:\s*auto\s*$' "$cfg"; then tmp="$(mktemp)" awk ' /^\s*agent:\s*auto\s*$/ { print "# Managed by dotfiles/home.nix home.activation.noMistakes"; - print "agent: [pi, opencode, grok, claude, codex]"; + print "agent: [opencode]"; next } { print } @@ -267,10 +323,9 @@ in fi if [ ! -f "$cfg" ]; then mkdir -p "$(dirname "$cfg")" - printf 'agent: [pi, opencode, grok, claude, codex]\n' > "$cfg" + printf 'agent: [opencode]\n' > "$cfg" fi # Ensure daemon running (launchd on macOS) "$bin" daemon restart >/dev/null 2>&1 || "$bin" daemon start >/dev/null 2>&1 || true ''; } - diff --git a/home/.config/firstmate/crew-dispatch.json b/home/.config/firstmate/crew-dispatch.json index a376c04..d2ce3de 100644 --- a/home/.config/firstmate/crew-dispatch.json +++ b/home/.config/firstmate/crew-dispatch.json @@ -1,20 +1,20 @@ { "rules": [ { - "when": "pure-function implementation with tests (indicators, slots, seasonal wiring, repositories)", - "use": [{ "harness": "pi", "model": "opencode-go/mimo-v2.5-pro" }], - "why": "MiMo V2.5 Pro (opencode-go, 1M ctx) produces clean correct code; flat-rate sub so $0 marginal cost. Pi drives it in an isolated worktree." + "when": "Well-specified implementation with clear acceptance criteria: pure functions, tests, repositories, adapters, or external-fetch integration.", + "use": [{ "harness": "opencode", "model": "opencode-go/deepseek-v4.1-flash", "provider": "opencode-go" }], + "why": "DeepSeek V4.1 Flash is the default OpenCode Go implementation worker; it is fast, economical, and strong on agentic coding tasks." }, { - "when": "adapter or external-fetch integration (COT, seed backfills, vendor seams)", - "use": [{ "harness": "pi", "model": "opencode-go/mimo-v2.5-pro" }], - "why": "Pattern-following work against existing adapter contracts; MiMo handles iterative fetch/debug loops." + "when": "UI work where supplied screenshots or other image context materially affect the implementation or verification.", + "use": [{ "harness": "opencode", "model": "opencode-go/glm-5.3-flash", "provider": "opencode-go" }], + "why": "GLM-5.3-Flash is the Go worker with image input; use it when visual context matters." }, { - "when": "frontend page or tRPC wiring (UI panels, router procedures, client exposure)", - "use": [{ "harness": "pi", "model": "opencode-go/mimo-v2.5-pro" }], - "why": "Mechanical wiring against existing components/routers; the contract carries the specialization." + "when": "Ambiguous investigation, difficult debugging, architectural tradeoffs, or broad changes with high uncertainty or blast radius.", + "use": [{ "harness": "opencode", "model": "opencode-go/gpt-6-luna", "provider": "opencode-go" }], + "why": "Reserve GPT-6 Luna for work that benefits from stronger reasoning than the fast implementation tier." } ], - "default": [{ "harness": "pi", "model": "opencode-go/mimo-v2.5-pro" }] -} \ No newline at end of file + "default": [{ "harness": "opencode", "model": "opencode-go/deepseek-v4.1-flash", "provider": "opencode-go" }] +} diff --git a/home/.config/opencode/opencode.json b/home/.config/opencode/opencode.json index 020f5c0..27881fa 100644 --- a/home/.config/opencode/opencode.json +++ b/home/.config/opencode/opencode.json @@ -1,6 +1,6 @@ { "$schema": "https://opencode.ai/config.json", - "model": "opencode/muse-spark-1.2-contributor-free", + "model": "opencode-go/gpt-6-luna", "instructions": ["AGENTS.md"], "provider": { "omlx": { diff --git a/home/.config/opencode2/opencode.json b/home/.config/opencode2/opencode.json index 3b1adbc..eeb00b6 100644 --- a/home/.config/opencode2/opencode.json +++ b/home/.config/opencode2/opencode.json @@ -1,6 +1,6 @@ { "$schema": "https://opencode.ai/config.json", - "model": "opencode/muse-spark-1.2-contributor-free", + "model": "opencode-go/gpt-6-luna", "autoupdate": false, "providers": { "omlx": { diff --git a/home/.grok/config.toml b/home/.grok/config.toml index e274b77..cf8c24c 100644 --- a/home/.grok/config.toml +++ b/home/.grok/config.toml @@ -7,7 +7,8 @@ name = "xAI Official" git = "https://github.com/xai-org/plugin-marketplace.git" [models] -default = "qwen" +default = "grok-4.5" +default_reasoning_effort = "high" [model.qwen] model = "Jundot/Qwen3.6-35B-A3B-oQ4-mtp" @@ -24,7 +25,7 @@ max_completion_tokens = 65536 theme = "rosepine" max_thoughts_width = 120 fork_secondary_model = "grok-build" -permission_mode = "always-approve" +permission_mode = "auto" yolo = false compact_mode = false @@ -32,4 +33,4 @@ compact_mode = false installer = "internal" [privacy] -privacy_banner_acked = "2026-09-21T16:02:21Z" +privacy_banner_acked = "2026-09-24T02:33:29Z"