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
This commit is contained in:
Lap Tran
2026-09-27 21:30:11 -04:00
parent a35c0bb744
commit e6fdd6884d
5 changed files with 84 additions and 28 deletions
+67 -12
View File
@@ -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
'';
}