diff --git a/.agents/shell/worktree.sh b/.agents/shell/worktree.sh
index 3dc2e7f3..cb4f7706 100644
--- a/.agents/shell/worktree.sh
+++ b/.agents/shell/worktree.sh
@@ -7,7 +7,7 @@
# shell que o chamou.
#
# No terminal (esta função), o script também imprime a diretiva `launch
-# opencode
--model deepseek/deepseek-v4-flash --auto [--prompt "…"]` (OPS26):
+# opencode --model cheapestinference/deepseek-v4-flash --auto [--prompt "…"]` (OPS26):
# a função executa o cd e então a linha (tokenizada por xargs — honra as aspas
# do prompt, nunca eval), e o TUI do opencode abre no worktree — `next` com
# `/work-issue --issue ` já enviado (OPS33: a Issue claimada vai no prompt),
diff --git a/.agents/skills/worktree-next-issue/SKILL.md b/.agents/skills/worktree-next-issue/SKILL.md
index 9d3a2929..d677201d 100644
--- a/.agents/skills/worktree-next-issue/SKILL.md
+++ b/.agents/skills/worktree-next-issue/SKILL.md
@@ -31,7 +31,7 @@ No opencode, isso é o comando **`/worktree next`** / **`/worktree kill`** (`.op
**Default-go:** `next`, `plan` e `new` imprimem `cd ` na última linha **por padrão**; `--stay` suprime; `--go` explícito continua aceito como no-op. No terminal interativo, use a função `worktree()` de **`.agents/shell/worktree.sh`** (uma linha de `source` no profile) para o `cd` ser aplicado de verdade no shell que te chamou — node não consegue mudar o cwd do shell pai. `kill` também imprime `cd ` no fim (a sessão nunca fica num diretório destruído).
-**Launch do opencode (OPS26 + OPS33 + OPS31):** só a função shell marca `TEQO_WORKTREE_TERMINAL=1`; com o marcador, `next`/`plan`/`new` imprimem também a diretiva `launch opencode --model deepseek/deepseek-v4-flash --auto [--prompt "/work-issue --issue "]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue ` já enviado (a Issue claimada vai no prompt; a skill lê o resto do Forgejo); `plan` abre com `/plan-issue` já enviado (OPS31: o TUI já cai no fluxo de planejamento); `new` abre sem `--prompt` ("apenas conversar"). Sem `exec`: sair do opencode volta ao shell no worktree. Presets são constantes em `scripts/lib/worktree.mjs`. **O comando `/worktree` do opencode (e qualquer automação sem o marcador) nunca lança o TUI.**
+**Launch do opencode (OPS26 + OPS33 + OPS31):** só a função shell marca `TEQO_WORKTREE_TERMINAL=1`; com o marcador, `next`/`plan`/`new` imprimem também a diretiva `launch opencode --model cheapestinference/deepseek-v4-flash --auto [--prompt "/work-issue --issue "]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue ` já enviado (a Issue claimada vai no prompt; a skill lê o resto do Forgejo); `plan` abre com `/plan-issue` já enviado (OPS31: o TUI já cai no fluxo de planejamento); `new` abre sem `--prompt` ("apenas conversar"). Sem `exec`: sair do opencode volta ao shell no worktree. Presets são constantes em `scripts/lib/worktree.mjs`. **O comando `/worktree` do opencode (e qualquer automação sem o marcador) nunca lança o TUI.**
## Fluxo quando invocado como skill (agentes que não têm opencode)
diff --git a/.opencode/commands/plan-issue.md b/.opencode/commands/plan-issue.md
index a0cb74e9..3485c5ae 100644
--- a/.opencode/commands/plan-issue.md
+++ b/.opencode/commands/plan-issue.md
@@ -1,6 +1,6 @@
---
description: Transforma ideias humanas em Issues GitHub + planos de intenção em docs/plans/ (com gate e registro)
-model: deepseek/deepseek-v4-flash
+model: cheapestinference/deepseek-v4-flash
---
Carregue a skill `plan-issue` (ferramenta de skills, nome exato) e siga o fluxo dela de ponta a ponta. A fonte canônica é `.agents/skills/plan-issue/SKILL.md` — não a transcreva nem recrie o fluxo.
diff --git a/.opencode/commands/work-issue.md b/.opencode/commands/work-issue.md
index ca9724ec..fea207dd 100644
--- a/.opencode/commands/work-issue.md
+++ b/.opencode/commands/work-issue.md
@@ -1,6 +1,6 @@
---
description: Executa uma Issue já claimada de ponta a ponta com supervisão humana (plano de implementação → pausa → execução → simplify → débitos → PR)
-model: deepseek/deepseek-v4-flash
+model: cheapestinference/deepseek-v4-flash
---
Carregue a skill `work-issue` (ferramenta de skills, nome exato) e siga o fluxo dela de ponta a ponta. A fonte canônica é `.agents/skills/work-issue/SKILL.md` — não a transcreva nem recrie o fluxo.
diff --git a/AGENTS.md b/AGENTS.md
index 83e164e6..6a47de5c 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -35,7 +35,7 @@ These are product/architecture constraints — not a ban on editing existing cod
- `Consent.text` was reconciled from `varchar` to `jsonb` via `20260715_163500_consent_text_to_jsonb` (matching the `richText` field). Any future field-type change is a migration, not a manual DB edit.
- To copy production content locally, use `pnpm db:pull` (`scripts/db-pull.mjs`): it only reads prod, only writes local, and excludes supporter PII (`contact`/`signature`/`subscription` row data).
- `pnpm db:doctor` diagnoses local database connectivity for the dev AND test targets: it names who holds the port, points at exited/crash-looping containers, and flags Postgres containers sharing one data volume (two postmasters on one PGDATA corrupt the WAL — this destroyed the local cluster's checkpoint on 2026-07-25; the canonical setup is ONE compose container on 5432 hosting `teqo` + `teqo_test`). `pnpm dev` runs the same preflight via `guard-dev-db` and refuses to start with a named remedy instead of a later ECONNREFUSED. `db:start`/`db:stop` pin the compose project with `-p teqo`, so they always target that ONE container even from a worktree directory. **`db:start` is idempotent (OPS37):** with `teqo-postgres-1` up and healthy it is a no-op — a plain `compose up` from another worktree would recreate the shared container and kill every live dev/e2e connection (the compose file's relative `./docker/postgres/init` bind mount makes the config hash differ per worktree); apply a real config/image change on purpose with `pnpm db:start --force-recreate`.
-- **Per-worktree environments (`pnpm worktree next`, 2026-08-08; default-go 2026-08-10):** parallel agents each get a deterministic isolated env — no fighting over port 3000, the shared `teqo_test`, or a second Postgres container. **`next` claims BEFORE creating the worktree (OPS33, 2026-08-10):** the same queue/order and optimistic lock as `pnpm agent:claim` (shared `claimIssue` in `scripts/lib/agent-github.mjs`); a failed claim prints the reason and stops with no orphan worktree; `--issue ` claims the directed issue (`ready`) or **reopens** an already-claimed one (`in-progress`, no re-claim, worktree reuse stays idempotent); the claim brief is printed and the output warns "já claimada — não rodar `pnpm agent:claim`" (`plan`/`new`/`kill` never touch Issues; the pool's coordinated `claimIssueForPool` is untouched). `worktree next [--issue N] [--stay]` provisions: a dev-server port `3100+slot` (slot = numeric part of the issue code, capped at 999 with hash fallback, bumped on collision among live worktrees), plus dedicated databases `teqo_wt` (dev) and `teqo_wt_test` (tests) created on the shared container with the full migration chain AND the minimal seed applied (`pnpm migrate` + `pnpm db:seed:minimal` per database — OPS28 parity: CI runs the same pair before e2e, so a worktree's `pnpm test:e2e` mirrors CI instead of failing on seed-dependent specs; the seed is idempotent and local-guarded, and `--no-migrate` skips both); writes `.env.local` + `.env.test.local` (gitignored, marker `# teqo worktree env (generated by pnpm worktree next)`; manual envs are never overwritten) and copies `PAYLOAD_SECRET`/`S3_*` (all-or-nothing)/VAPID from the main repo — plus the gitignored `.opencode/secrets/*` (e.g. `penpot-token`, referenced by the worktree's `opencode.json` MCP config), without which opencode refuses to launch ("bad file reference" for the dangling `{file:…}`). **`next`/`plan`/`new` print `cd ` as the last line BY DEFAULT** — the caller applies it (shell function `worktree()` in `.agents/shell/worktree.sh`, or the `/worktree` opencode command); `--stay` suppresses the cd, `--go` explicit stays accepted as a no-op (it was the old default), and `kill` ends with `cd ` so the shell never sits in a destroyed directory. **In the interactive terminal the shell function sets `TEQO_WORKTREE_TERMINAL=1` and `next`/`plan`/`new` additionally print a `launch opencode --model deepseek/deepseek-v4-flash --auto [--prompt "/work-issue --issue "]` directive BEFORE the `cd` line, which the function executes after the cd (OPS26, 2026-08-10; OPS33: `next` sends `/work-issue --issue ` — the claimed issue — with the prompt value quoted, and the shell tokenizes the line via xargs, quote-aware, never eval; OPS31 for `plan`): `next` opens the opencode TUI in the worktree with `/work-issue --issue ` already sent (the OPS25 command runs the whole cycle; the skill reads the rest from the Issue), `plan` opens with `/plan-issue` already sent (the TUI lands straight in the planning flow), `new` opens with no prompt ("apenas conversar", no skill — the opencode CLI's `--prompt` always auto-submits, there is no prefill-without-submit; that stays an upstream-only feature request, annotated in the opencode proposition). The launch is without `exec` (exiting the TUI returns to the shell in the worktree, no auto-`kill`), `--stay` suppresses both the cd and the launch (the claim still happens), the presets are constants in `scripts/lib/worktree.mjs` (`OPENCODE_PRESET_MODEL`, `OPENCODE_SKILL_COMMAND_BY_PURPOSE`, unit-tested), and **the `/worktree` opencode command never launches a TUI** (no marker — no nested TUI). `worktree plan [bag] [--stay]` (2026-08-08) is the sibling for the `/plan-issue` skill: **each invocation creates a DIFFERENT planning worktree** so parallel `/plan-issue` sessions never share one — branch `plans/plan-issue-` when a `bag` slug is given (suffixed `-2`/`-3` if that name is taken) or the next free sequential `plans/plan-issue-` when not (`PLAN_BRANCH_PREFIX`/`planBranchName`, `scripts/lib/worktree.mjs`); the lowercase `plans/…` prefix deliberately never matches `next`'s uppercase-led `-`, so a later `next` never collides in branch or slot. `worktree new [bag] [--stay]` (OPS27, 2026-08-10) is the NEUTRAL sibling: a worktree with **no pre-defined function\*\* (explore an idea, chat, plan without registering anything) — also a DIFFERENT one per invocation, branch `work/` (suffixed `-2`/`-3` on collision) or the next free sequential `work/` (`WORK_BRANCH_PREFIX`/`workBranchName`, same `namespaceBranchName` core as `plan`); the lowercase `work/…` prefix collides with neither `next` nor `plan`, and the provisioning is identical with `purpose: 'new'` (env comment `gerado por pnpm worktree new`; the frozen env marker keeps its historical `…next` text). `kill` drops the worktree's generated databases best-effort. Tests read `.env.test.local` after `.env.test` (vitest.setup.ts / playwright.config.ts / db-doctor / gate-ci mirror the layering), and `assertTestDatabase` accepts `teqo_test` or `teqo__test` on localhost only — still fail-closed on remote. Pure derivation lives in `scripts/lib/worktree-env.mjs` (unit-tested). Without Docker (Cursor Cloud) it degrades to the shared `teqo`/`teqo_test` with a warning — and still runs migrate + seed mínimo on those shared databases (same parity; the seed re-pins campaignGoals and 5 municipalities there, overwriting manual tweaks).
+- **Per-worktree environments (`pnpm worktree next`, 2026-08-08; default-go 2026-08-10):** parallel agents each get a deterministic isolated env — no fighting over port 3000, the shared `teqo_test`, or a second Postgres container. **`next` claims BEFORE creating the worktree (OPS33, 2026-08-10):** the same queue/order and optimistic lock as `pnpm agent:claim` (shared `claimIssue` in `scripts/lib/agent-github.mjs`); a failed claim prints the reason and stops with no orphan worktree; `--issue ` claims the directed issue (`ready`) or **reopens** an already-claimed one (`in-progress`, no re-claim, worktree reuse stays idempotent); the claim brief is printed and the output warns "já claimada — não rodar `pnpm agent:claim`" (`plan`/`new`/`kill` never touch Issues; the pool's coordinated `claimIssueForPool` is untouched). `worktree next [--issue N] [--stay]` provisions: a dev-server port `3100+slot` (slot = numeric part of the issue code, capped at 999 with hash fallback, bumped on collision among live worktrees), plus dedicated databases `teqo_wt` (dev) and `teqo_wt_test` (tests) created on the shared container with the full migration chain AND the minimal seed applied (`pnpm migrate` + `pnpm db:seed:minimal` per database — OPS28 parity: CI runs the same pair before e2e, so a worktree's `pnpm test:e2e` mirrors CI instead of failing on seed-dependent specs; the seed is idempotent and local-guarded, and `--no-migrate` skips both); writes `.env.local` + `.env.test.local` (gitignored, marker `# teqo worktree env (generated by pnpm worktree next)`; manual envs are never overwritten) and copies `PAYLOAD_SECRET`/`S3_*` (all-or-nothing)/VAPID from the main repo — plus the gitignored `.opencode/secrets/*` (e.g. `penpot-token`, referenced by the worktree's `opencode.json` MCP config), without which opencode refuses to launch ("bad file reference" for the dangling `{file:…}`). **`next`/`plan`/`new` print `cd ` as the last line BY DEFAULT** — the caller applies it (shell function `worktree()` in `.agents/shell/worktree.sh`, or the `/worktree` opencode command); `--stay` suppresses the cd, `--go` explicit stays accepted as a no-op (it was the old default), and `kill` ends with `cd ` so the shell never sits in a destroyed directory. **In the interactive terminal the shell function sets `TEQO_WORKTREE_TERMINAL=1` and `next`/`plan`/`new` additionally print a `launch opencode --model cheapestinference/deepseek-v4-flash --auto [--prompt "/work-issue --issue "]` directive BEFORE the `cd` line, which the function executes after the cd (OPS26, 2026-08-10; OPS33: `next` sends `/work-issue --issue ` — the claimed issue — with the prompt value quoted, and the shell tokenizes the line via xargs, quote-aware, never eval; OPS31 for `plan`): `next` opens the opencode TUI in the worktree with `/work-issue --issue ` already sent (the OPS25 command runs the whole cycle; the skill reads the rest from the Issue), `plan` opens with `/plan-issue` already sent (the TUI lands straight in the planning flow), `new` opens with no prompt ("apenas conversar", no skill — the opencode CLI's `--prompt` always auto-submits, there is no prefill-without-submit; that stays an upstream-only feature request, annotated in the opencode proposition). The launch is without `exec` (exiting the TUI returns to the shell in the worktree, no auto-`kill`), `--stay` suppresses both the cd and the launch (the claim still happens), the presets are constants in `scripts/lib/worktree.mjs` (`OPENCODE_PRESET_MODEL`, `OPENCODE_SKILL_COMMAND_BY_PURPOSE`, unit-tested), and **the `/worktree` opencode command never launches a TUI** (no marker — no nested TUI). `worktree plan [bag] [--stay]` (2026-08-08) is the sibling for the `/plan-issue` skill: **each invocation creates a DIFFERENT planning worktree** so parallel `/plan-issue` sessions never share one — branch `plans/plan-issue-` when a `bag` slug is given (suffixed `-2`/`-3` if that name is taken) or the next free sequential `plans/plan-issue-` when not (`PLAN_BRANCH_PREFIX`/`planBranchName`, `scripts/lib/worktree.mjs`); the lowercase `plans/…` prefix deliberately never matches `next`'s uppercase-led `-`, so a later `next` never collides in branch or slot. `worktree new [bag] [--stay]` (OPS27, 2026-08-10) is the NEUTRAL sibling: a worktree with **no pre-defined function\*\* (explore an idea, chat, plan without registering anything) — also a DIFFERENT one per invocation, branch `work/` (suffixed `-2`/`-3` on collision) or the next free sequential `work/` (`WORK_BRANCH_PREFIX`/`workBranchName`, same `namespaceBranchName` core as `plan`); the lowercase `work/…` prefix collides with neither `next` nor `plan`, and the provisioning is identical with `purpose: 'new'` (env comment `gerado por pnpm worktree new`; the frozen env marker keeps its historical `…next` text). `kill` drops the worktree's generated databases best-effort. Tests read `.env.test.local` after `.env.test` (vitest.setup.ts / playwright.config.ts / db-doctor / gate-ci mirror the layering), and `assertTestDatabase` accepts `teqo_test` or `teqo__test` on localhost only — still fail-closed on remote. Pure derivation lives in `scripts/lib/worktree-env.mjs` (unit-tested). Without Docker (Cursor Cloud) it degrades to the shared `teqo`/`teqo_test` with a warning — and still runs migrate + seed mínimo on those shared databases (same parity; the seed re-pins campaignGoals and 5 municipalities there, overwriting manual tweaks).
- To (re)populate news content, `pnpm db:seed:posts` fetches articles live from jorgesolla.com.br into the LOCAL db (same non-local `DATABASE_URL` guard as `pnpm dev`). It writes from a CLI process outside the deployed runtime, so after seeding — or after ANY direct-DB change — you must bust the production `posts` cache via `POST /api/revalidate`. See "Posts & Tags" below.
- To (re)populate the TSE 2022 election baseline, `pnpm db:seed:tse` downloads TSE open data and imports the Bahia scope into the LOCAL db (same guard). Since the 2026-07-23 hardening, elections-tab reads are cached under the `election-tse` tag — after re-seeding a database the deployed app reads, bust it via `POST /api/revalidate?tag=election-tse`. See "Election baseline data (TSE 2022)" below.
diff --git a/opencode.json b/opencode.json
index 73e2a530..4653e50f 100644
--- a/opencode.json
+++ b/opencode.json
@@ -6,30 +6,5 @@
"url": "https://design.penpot.app/mcp/stream?userToken={file:.opencode/secrets/penpot-token}",
"enabled": true
}
- },
- "provider": {
- "cheapest-inference": {
- "npm": "@ai-sdk/openai-compatible",
- "name": "Cheapest Inference",
- "options": {
- "baseURL": "https://api.cheapestinference.com/v1"
- },
- "models": {
- "deepseek-v4-flash": {
- "name": "DeepSeek V4 Flash",
- "limit": {
- "context": 1000000,
- "output": 384000
- }
- },
- "mimo-v2.5": {
- "name": "MiMo v2.5",
- "limit": {
- "context": 1000000,
- "output": 128000
- }
- }
- }
- }
}
}
diff --git a/scripts/lib/worktree.mjs b/scripts/lib/worktree.mjs
index 385ccae3..c3c60ab1 100644
--- a/scripts/lib/worktree.mjs
+++ b/scripts/lib/worktree.mjs
@@ -19,8 +19,16 @@ export const PLAN_BRANCH_PREFIX = 'plans/plan-issue'
/** Env var the interactive-terminal `worktree()` function sets to request the opencode launch. */
export const WORKTREE_TERMINAL_ENV = 'TEQO_WORKTREE_TERMINAL'
-/** Preset model for the opencode launch — change the preset by editing this constant. */
-export const OPENCODE_PRESET_MODEL = 'deepseek/deepseek-v4-flash'
+/**
+ * Preset model for the opencode launch — change the preset by editing this
+ * constant. Provider `cheapestinference` (Cheapest Inference, global config
+ * in ~/.config/opencode/opencode.jsonc; auth key via `opencode auth login
+ * cheapestinference`). The `max` variant is the default because opencode's
+ * TUI has no `--variant` flag — the per-model variant is persisted in
+ * ~/.local/state/opencode/model.json (`variant["cheapestinference/deepseek-v4-flash"]
+ * = "max"`), applied automatically when the TUI opens with this model.
+ */
+export const OPENCODE_PRESET_MODEL = 'cheapestinference/deepseek-v4-flash'
/**
* Skill command sent as the launch's initial message per purpose. `next`
diff --git a/scripts/worktree.mjs b/scripts/worktree.mjs
index 9d7e69f8..dc84bf19 100644
--- a/scripts/worktree.mjs
+++ b/scripts/worktree.mjs
@@ -24,7 +24,7 @@
* Chamado do terminal interativo (com
* `TEQO_WORKTREE_TERMINAL=1`, que só a função shell
* seta), imprime também a diretiva `launch
- * opencode --model deepseek/deepseek-v4-flash
+ * opencode --model cheapestinference/deepseek-v4-flash
* --auto --prompt "/work-issue --issue "` ANTES
* do `cd` — a função shell executa o cd e então a
* linha, e o TUI do opencode abre no worktree com
@@ -775,7 +775,7 @@ if (!subcommand) {
console.log(' opencode command, ou a função `worktree()` de .agents/shell/worktree.sh);')
console.log(' no terminal (TEQO_WORKTREE_TERMINAL=1) imprime também a diretiva')
console.log(' `launch opencode … --prompt "/work-issue --issue "` (OPS26+OPS33:')
- console.log(' abre o TUI com deepseek/deepseek-v4-flash + auto + a Issue claimada já')
+ console.log(' abre o TUI com cheapestinference/deepseek-v4-flash + auto + a Issue claimada já')
console.log(' informada); --stay suprime cd e launch (o claim ainda acontece); --go')
console.log(' explícito continua aceito como no-op; --no-migrate pula migrations e o')
console.log(' seed mínimo (db:seed:minimal) nos bancos novos (OPS28: paridade com a CI)')
diff --git a/tests/unit/opencodeCommands.unit.spec.ts b/tests/unit/opencodeCommands.unit.spec.ts
index 6ec0840a..09bc5fc8 100644
--- a/tests/unit/opencodeCommands.unit.spec.ts
+++ b/tests/unit/opencodeCommands.unit.spec.ts
@@ -34,7 +34,7 @@ describe('opencode commands couple to their skill by exact name', () => {
/^description: .+$/m,
)
expect(frontmatter![1], 'frontmatter must pin the preference model').toMatch(
- /^model: deepseek\/deepseek-v4-flash$/m,
+ /^model: cheapestinference\/deepseek-v4-flash$/m,
)
})
})
diff --git a/tests/unit/worktree.unit.spec.ts b/tests/unit/worktree.unit.spec.ts
index ab0fe2e9..65c234d6 100644
--- a/tests/unit/worktree.unit.spec.ts
+++ b/tests/unit/worktree.unit.spec.ts
@@ -148,7 +148,7 @@ describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33)
it('next launches with the preset model, --auto and the /work-issue command sent (value always quoted)', () => {
expect(opencodeLaunchDirective({ dir, purpose: 'next', terminal: true })).toBe(
- `launch opencode ${dir} --model deepseek/deepseek-v4-flash --auto --prompt "/work-issue"`,
+ `launch opencode ${dir} --model cheapestinference/deepseek-v4-flash --auto --prompt "/work-issue"`,
)
})
@@ -156,33 +156,33 @@ describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33)
expect(
opencodeLaunchDirective({ dir, purpose: 'next', terminal: true, issueNumber: 595 }),
).toBe(
- `launch opencode ${dir} --model deepseek/deepseek-v4-flash --auto --prompt "/work-issue --issue 595"`,
+ `launch opencode ${dir} --model cheapestinference/deepseek-v4-flash --auto --prompt "/work-issue --issue 595"`,
)
})
it('plan launches with the same presets and /plan-issue sent (OPS31, value quoted)', () => {
expect(opencodeLaunchDirective({ dir, purpose: 'plan', terminal: true })).toBe(
- `launch opencode ${dir} --model deepseek/deepseek-v4-flash --auto --prompt "/plan-issue"`,
+ `launch opencode ${dir} --model cheapestinference/deepseek-v4-flash --auto --prompt "/plan-issue"`,
)
})
it('new launches prompt-less too — "apenas conversar", no skill sent', () => {
expect(opencodeLaunchDirective({ dir, purpose: 'new', terminal: true })).toBe(
- `launch opencode ${dir} --model deepseek/deepseek-v4-flash --auto`,
+ `launch opencode ${dir} --model cheapestinference/deepseek-v4-flash --auto`,
)
})
it('plan/new ignore the issueNumber — only next carries the claimed issue', () => {
expect(opencodeLaunchDirective({ dir, purpose: 'plan', terminal: true, issueNumber: 7 })).toBe(
- `launch opencode ${dir} --model deepseek/deepseek-v4-flash --auto --prompt "/plan-issue"`,
+ `launch opencode ${dir} --model cheapestinference/deepseek-v4-flash --auto --prompt "/plan-issue"`,
)
expect(opencodeLaunchDirective({ dir, purpose: 'new', terminal: true, issueNumber: 7 })).toBe(
- `launch opencode ${dir} --model deepseek/deepseek-v4-flash --auto`,
+ `launch opencode ${dir} --model cheapestinference/deepseek-v4-flash --auto`,
)
})
it('pins the preset constants — changing the model is editing a constant', () => {
- expect(OPENCODE_PRESET_MODEL).toBe('deepseek/deepseek-v4-flash')
+ expect(OPENCODE_PRESET_MODEL).toBe('cheapestinference/deepseek-v4-flash')
expect(WORKTREE_TERMINAL_ENV).toBe('TEQO_WORKTREE_TERMINAL')
expect(OPENCODE_SKILL_COMMAND_BY_PURPOSE).toEqual({
next: '/work-issue',
@@ -193,7 +193,7 @@ describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33)
it('an unknown purpose degrades to a prompt-less launch (fail-safe direction)', () => {
expect(opencodeLaunchDirective({ dir, purpose: 'bogus', terminal: true })).toBe(
- `launch opencode ${dir} --model deepseek/deepseek-v4-flash --auto`,
+ `launch opencode ${dir} --model cheapestinference/deepseek-v4-flash --auto`,
)
})
})