mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
fix(worktree): OPS95 — corrige mapa de modelos e remove --variant do launch do TUI (Closes #876)
This commit is contained in:
parent
d48914858a
commit
d679708c06
9 changed files with 193 additions and 65 deletions
|
|
@ -7,16 +7,17 @@
|
|||
# shell que o chamou.
|
||||
#
|
||||
# No terminal (esta função), o script também imprime a diretiva `launch
|
||||
# opencode <dir> --model <preset|map> --variant max --auto [--prompt "…"]` (OPS26+OPS33+OPS93):
|
||||
# opencode <dir> --model <preset|map> --auto [--prompt "…"]` (OPS26+OPS33+OPS93+OPS95):
|
||||
# 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 <N>` já enviado (OPS33: a Issue claimada vai no prompt),
|
||||
# `plan` com `/plan-issue` já enviado (OPS31), `new` sem prompt (apenas
|
||||
# conversar), sempre em `--variant max` (OPS78 guardrail; falha alto se a variante
|
||||
# não existir). Modelo por invocação: `--cheap` (cheapestinference/deepseek-v4-flash),
|
||||
# `--pro` (opencode-go/qwen3.7-max), `--zen` (opencode-go/ox-alpha-free),
|
||||
# `--go` (opencode-go/mimo-v2.5), `--alibaba` (alibaba-token-plan/qwen3.7-max) no
|
||||
# mapa fixo `WORKTREE_MODEL_MAP` (OPS93); sem flag o preset `deepseek/deepseek-v4-flash`
|
||||
# conversar). Sem `--variant` (OPS95: o yargs do TUI rejeita o flag e só
|
||||
# imprime o helper; variantes ficam na config global da máquina, via Ctrl+T).
|
||||
# Modelo por invocação: `--cheap` (cheapestinference/deepseek-v4-flash),
|
||||
# `--pro` (deepseek/deepseek-v4-pro), `--zen` (opencode-go/ox-alpha-free),
|
||||
# `--go` (opencode-go/hy3), `--alibaba` (alibaba-token-plan/deepseek-v4-flash) no
|
||||
# mapa fixo `WORKTREE_MODEL_MAP` (OPS93 menu; valores OPS95); sem flag o preset `deepseek/deepseek-v4-flash`
|
||||
# permanece. Sem `exec` de propósito: ao sair do opencode, o terminal volta ao
|
||||
# shell dentro do worktree. Presets são constantes em scripts/lib/worktree.mjs;
|
||||
# o marcador TEQO_WORKTREE_TERMINAL=1 é o que separa esta superfície da do comando
|
||||
|
|
@ -47,8 +48,8 @@
|
|||
# --stay não troca; flag de modelo como no `next`
|
||||
# worktree kill [--force] destrói o worktree atual e cd para o main por padrão
|
||||
#
|
||||
# `--go` remapeado em OPS93 para o mapa `opencode-go/mimo-v2.5` (antes no-op do OPS24).
|
||||
# Claim determinístico: `next` claima antes de criar o worktree (mesma fila e
|
||||
# `--go` remapeado em OPS93 para o provider OpenCode Go e em OPS95 para o modelo `opencode-go/hy3`
|
||||
# (antes no-op do OPS24). Claim determinístico: `next` claima antes de criar o worktree (mesma fila e
|
||||
# lock de `pnpm agent:claim`); `plan`/`new`/`kill` não tocam Issues.
|
||||
|
||||
worktree() {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ VMs Cloud **não rodam** `docker compose` / `pnpm db:start`. Postgres nativo: `.
|
|||
|
||||
## Per-worktree environments (`pnpm worktree next`)
|
||||
|
||||
Parallel agents must not fight over port 3000, the shared `teqo_test`, or a second Postgres container. `pnpm worktree next [--stay] [--cheap|--pro|--zen|--go|--alibaba]` provisions each worktree with a deterministic isolated env (`next`/`plan`/`new` print `cd <dir>` by default — apply it, or pass `--stay` to suppress; `--cheap/--pro/--zen/--go/--alibaba` selects the model per invocation via `WORKTREE_MODEL_MAP` with `--variant max`):
|
||||
Parallel agents must not fight over port 3000, the shared `teqo_test`, or a second Postgres container. `pnpm worktree next [--stay] [--cheap|--pro|--zen|--go|--alibaba]` provisions each worktree with a deterministic isolated env (`next`/`plan`/`new` print `cd <dir>` by default — apply it, or pass `--stay` to suppress; `--cheap/--pro/--zen/--go/--alibaba` selects the model per invocation via `WORKTREE_MODEL_MAP`):
|
||||
|
||||
- `slot` = numeric part of the issue code (`C15` → 15, `B164` → 164; hash fallback without digits; bumped on collision among live worktrees).
|
||||
- Dev server port `3100+slot`; databases `teqo_wt<slot>` (dev) and `teqo_wt<slot>_test` (tests), created on the **one shared container** with the full migration chain **and the minimal seed** applied (one-time, ~30 s each; OPS28 parity with CI, which runs `migrate → seed:minimal` before e2e — a worktree's `pnpm test:e2e` mirrors CI).
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ No opencode, isso é o comando **`/worktree next`** / **`/worktree kill`** (`.op
|
|||
|
||||
`plan` é o primo do `next`: worktree de **planejamento** para rodar a skill `/plan-issue` sem ocupar o main. **Cada invocação cria um DIFERENTE** (sessões paralelas): com `bag` opcional → branch `plans/plan-issue-<bag>` (sufixo `-2`/`-3` se o nome já estiver vivo); sem `bag` → próximo sequencial `plans/plan-issue-<n>` livre. Não é nomeado por Issue nenhuma — proposital, para um `next` posterior da próxima Issue nunca colidir em branch nem em slot (prefixo minúsculo `plans/…` vs branch `<Code>-<slug>` sempre uppercase-led). `new` é o irmão **neutro** (sem função pré-definida — explorar ideia, conversar, planejar sem registrar): mesma semântica de "um DIFERENTE por invocação", branch `work/<bag>` (sufixo `-2`/`-3` em colisão) ou `work/<n>` sequencial, prefixo `work/…` que não colide com `next` nem `plan`. O fluxo desta skill (fila → próxima Issue → implementação) é só `next`.
|
||||
|
||||
**Default-go:** `next`, `plan` e `new` imprimem `cd <dir>` na última linha **por padrão**; `--stay` suprime; modelos por invocação via `--cheap/--pro/--zen/--go/--alibaba` (mapa fixo `WORKTREE_MODEL_MAP`, at-most-one; sem flag o preset permanece); `--go` remapeado em OPS93 para `opencode-go/mimo-v2.5` (antes no-op do OPS24). 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 <main>` no fim (a sessão nunca fica num diretório destruído).
|
||||
**Default-go:** `next`, `plan` e `new` imprimem `cd <dir>` na última linha **por padrão**; `--stay` suprime; modelos por invocação via `--cheap/--pro/--zen/--go/--alibaba` (mapa fixo `WORKTREE_MODEL_MAP`, at-most-one; sem flag o preset permanece); `--go` remapeado em OPS93 para o provider OpenCode Go e em OPS95 para `opencode-go/hy3` (antes no-op do OPS24). 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 <main>` no fim (a sessão nunca fica num diretório destruído).
|
||||
|
||||
**Launch do opencode (OPS26 + OPS33 + OPS31 + OPS93):** só a função shell marca `TEQO_WORKTREE_TERMINAL=1`; com o marcador, `next`/`plan`/`new` imprimem também a diretiva `launch opencode <dir> --model <preset|map> --variant max --auto [--prompt "/work-issue --issue <N>"]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue <N>` já enviado (a Issue claimada vai no prompt; a skill lê o resto do GitHub) em `--variant max` (sempre, falha alto se a variante não existir); `plan` abre com `/plan-issue` já enviado (OPS31: o TUI já cai no fluxo de planejamento); `new` abre sem `--prompt` ("apenas conversar"). Modelo por invocação via `--cheap` (cheapestinference/deepseek-v4-flash), `--pro` (opencode-go/qwen3.7-max), `--zen` (opencode-go/ox-alpha-free), `--go` (opencode-go/mimo-v2.5), `--alibaba` (alibaba-token-plan/qwen3.7-max); sem flag o preset `deepseek/deepseek-v4-flash` permanece; variantes low/high/max do model override na config global do opencode (`~/.config/opencode/opencode.jsonc`), selecionáveis no TUI e sticky por model. Sem `exec`: sair do opencode volta ao shell no worktree. Presets e mapa 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 + OPS93 + OPS95):** só a função shell marca `TEQO_WORKTREE_TERMINAL=1`; com o marcador, `next`/`plan`/`new` imprimem também a diretiva `launch opencode <dir> --model <preset|map> --auto [--prompt "/work-issue --issue <N>"]` **antes** do `cd`, e a função a executa depois do cd — `next` abre o TUI com `/work-issue --issue <N>` já enviado (a Issue claimada vai no prompt; a skill lê o resto do GitHub); `plan` abre com `/plan-issue` já enviado (OPS31: o TUI já cai no fluxo de planejamento); `new` abre sem `--prompt` ("apenas conversar"). Sem `--variant` na diretiva (OPS95: o yargs do TUI rejeita o flag desconhecido e só imprime o helper — variantes ficam na config global do opencode, selecionáveis via Ctrl+T; `opencode run --variant max` segue sendo a via CLI para runs headless). Modelo por invocação via `--cheap` (cheapestinference/deepseek-v4-flash), `--pro` (deepseek/deepseek-v4-pro), `--zen` (opencode-go/ox-alpha-free), `--go` (opencode-go/hy3), `--alibaba` (alibaba-token-plan/deepseek-v4-flash) — valores corrigidos no OPS95; sem flag o preset `deepseek/deepseek-v4-flash` permanece. Sem `exec`: sair do opencode volta ao shell no worktree. Presets e mapa 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)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ description: Claima a próxima Issue (next [--issue N] [--stay] [--cheap|--pro|-
|
|||
|
||||
Rode o script determinístico abaixo (não improvise a lógica) e reporte o resultado de forma concisa.
|
||||
|
||||
- `next [--issue N] [--stay] [--cheap|--pro|--zen|--go|--alibaba]`: **claima** a próxima Issue claimável da fila (mesma fila/ordem e lock otimista de `pnpm agent:claim`) e cria (ou reutiliza) o worktree dela. Claim falhou → reporte o motivo — não há worktree. `--issue N` claima a Issue direcionada (`ready`) ou **reabre** uma já claimada (`in-progress`, sem re-claim). A saída avisa "já claimada — NÃO rodar `pnpm agent:claim`". Por padrão o script imprime `cd <dir>` na última linha — aplique-o na sessão de shell atual (`cd <dir>`) e reporte o novo diretório. `--stay` suprime o `cd` (não troque de diretório) mas o claim ainda acontece. `--cheap/--pro/--zen/--go/--alibaba` escolhe o modelo por invocação no mapa fixo `WORKTREE_MODEL_MAP` (cheap=cheapestinference/deepseek-v4-flash, pro=opencode-go/qwen3.7-max, zen=opencode-go/ox-alpha-free, go=opencode-go/mimo-v2.5, alibaba=alibaba-token-plan/qwen3.7-max) com `--variant max` sempre; at-most-one (múltiplas → erro).
|
||||
- `next [--issue N] [--stay] [--cheap|--pro|--zen|--go|--alibaba]`: **claima** a próxima Issue claimável da fila (mesma fila/ordem e lock otimista de `pnpm agent:claim`) e cria (ou reutiliza) o worktree dela. Claim falhou → reporte o motivo — não há worktree. `--issue N` claima a Issue direcionada (`ready`) ou **reabre** uma já claimada (`in-progress`, sem re-claim). A saída avisa "já claimada — NÃO rodar `pnpm agent:claim`". Por padrão o script imprime `cd <dir>` na última linha — aplique-o na sessão de shell atual (`cd <dir>`) e reporte o novo diretório. `--stay` suprime o `cd` (não troque de diretório) mas o claim ainda acontece. `--cheap/--pro/--zen/--go/--alibaba` escolhe o modelo por invocação no mapa fixo `WORKTREE_MODEL_MAP` (cheap=cheapestinference/deepseek-v4-flash, pro=deepseek/deepseek-v4-pro, zen=opencode-go/ox-alpha-free, go=opencode-go/hy3, alibaba=alibaba-token-plan/deepseek-v4-flash); at-most-one (múltiplas → erro).
|
||||
- `plan [bag] [--stay] [--cheap|--pro|--zen|--go|--alibaba]`: cria um worktree de planejamento **diferente a cada invocação** (branch `plans/plan-issue-<bag>`, ou `plans/plan-issue-<n>` sequencial sem bag; sufixo `-2`/`-3` em colisão) para rodar `/plan-issue` sem ocupar o main; nunca conflita com `next`. Não claima nada. Mesmo contrato de `cd` do `next`: aplique a última linha `cd <dir>` por padrão; `--stay` suprime; flag de modelo como no `next`.
|
||||
- `new [bag] [--stay] [--cheap|--pro|--zen|--go|--alibaba]`: cria um worktree **neutro** (sem função pré-definida — explorar ideia, conversar, planejar sem registrar nada) **diferente a cada invocação** (branch `work/<bag>`, ou `work/<n>` sequencial sem bag; sufixo `-2`/`-3` em colisão); o prefixo minúsculo `work/…` nunca conflita com `next` nem `plan`. Não claima nada. Mesmo contrato de `cd` do `plan`: aplique a última linha `cd <dir>` por padrão; `--stay` suprime; flag de modelo como no `next`.
|
||||
- `kill [--force]`: destrói o worktree em que você está e remove seus bancos. O script imprime `cd <main>` na última linha — aplique-o (`cd <main>`) para a sessão sair do diretório destruído.
|
||||
|
||||
> **Este comando roda SEM o marcador `TEQO_WORKTREE_TERMINAL`, então nunca recebe a diretiva `launch`** — só o `cd`. O launch do opencode (OPS26/OPS33+OPS93, com `--variant max`) acontece apenas na função `worktree()` de `.agents/shell/worktree.sh` (terminal interativo); nunca abra um TUI aninhado a partir daqui.
|
||||
> **Este comando roda SEM o marcador `TEQO_WORKTREE_TERMINAL`, então nunca recebe a diretiva `launch`** — só o `cd`. O launch do opencode (OPS26/OPS33+OPS93+OPS95, sem `--variant` — o TUI rejeita o flag) acontece apenas na função `worktree()` de `.agents/shell/worktree.sh` (terminal interativo); nunca abra um TUI aninhado a partir daqui.
|
||||
|
||||
!`node scripts/worktree.mjs $ARGUMENTS`
|
||||
|
|
|
|||
1
docs/changelog/2026-08-24-ops95.md
Normal file
1
docs/changelog/2026-08-24-ops95.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
**OPS95 — Corrigir mapa de modelos e launch do worktree CLI, follow-up OPS93 (2026-08-24):** `opencodeLaunchDirective` deixa de emitir `--variant max` — o yargs do TUI do opencode rejeita o flag desconhecido e saía no helper em vez de abrir (quebra incondicional do OPS93 em next/plan/new); `WORKTREE_VARIANT` eliminada e o conceito "effort max na diretiva" sai junto (variantes ficam na config global da máquina via Ctrl+T; `opencode run --variant max` segue a via headless). Mapa `WORKTREE_MODEL_MAP` corrigido no GATE para os IDs pedidos: pro=deepseek/deepseek-v4-pro, go=opencode-go/hy3, alibaba=alibaba-token-plan/deepseek-v4-flash (cheap/zen mantidos); chaves, preset e guardrail at-most-one intactos. As 7 superfícies que citam o mapa/diretiva sincronizadas na mesma entrega (`scripts/lib/worktree.mjs`, `scripts/worktree.mjs` docblock/help incl. resquício "`--go` é no-op" do kill, `.agents/shell/worktree.sh`, `.opencode/commands/worktree.md`, skills `worktree-next-issue` e `local-database`) + pins de `tests/unit/worktree.unit.spec.ts`.
|
||||
108
docs/plans/worktree-flags-modelo-correcao-impl.md
Normal file
108
docs/plans/worktree-flags-modelo-correcao-impl.md
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Impl: Corrigir mapa de modelos e launch do worktree CLI (follow-up OPS93)
|
||||
|
||||
Status: rascunho
|
||||
Atualizado em: 2026-08-24
|
||||
Issue: #876
|
||||
Intenção: docs/plans/worktree-flags-modelo-correcao.md
|
||||
Appetite restante: ~0,5 dia (herdado)
|
||||
|
||||
## Leitura da intenção
|
||||
|
||||
- **Outcome:** `pnpm worktree next/plan/new` volta a abrir o TUI sozinho (`--variant` sai da diretiva — o yargs do TUI rejeita o flag desconhecido) e as 5 flags apontam para o mapa de modelos corrigido; as superfícies que citam o mapa/diretiva saem sincronizadas na mesma entrega; sem flag, preset `deepseek/deepseek-v4-flash` intacto.
|
||||
- **O que NÃO negociar:** cardápio fechado de 5 flags (`--cheap|--pro|--zen|--go|--alibaba`, mesmas chaves); preset sem flag; sem persistência de preferência; sem tocar `/work-issue`/`plan-issue`; sem editar config global de variantes da máquina via repo; fora do terminal interativo (`TEQO_WORKTREE_TERMINAL≠1`) as flags continuam irrelevantes.
|
||||
- **O que reavaliar:** hipótese de direção confirmada linha a linha pelo explorador (ver abaixo). O mapa-alvo não estava registrado por escrito em nenhum artefato acessível (#876/#859, planos OPS93) — foi fornecido e travado pelo humano no GATE desta entrega; tabela na decisão 2 abaixo.
|
||||
|
||||
## Estado atual verificado (explorador)
|
||||
|
||||
- `scripts/lib/worktree.mjs`: mapa L43-49 (`cheap=cheapestinference/deepseek-v4-flash`, `pro=opencode-go/qwen3.7-max`, `zen=opencode-go/ox-alpha-free`, `go=opencode-go/mimo-v2.5`, `alibaba=alibaba-token-plan/qwen3.7-max`); `WORKTREE_VARIANT='max'` L54-55; docblocks L40-41 e L171-177 citam `--variant max`; erro de conflito lista flags L66; diretiva monta `[dir,'--model',selectedModel,'--variant',WORKTREE_VARIANT,'--auto']` em **L198**; preset L34-35 (`deepseek/deepseek-v4-flash`, override `OPENCODE_WORKTREE_MODEL`).
|
||||
- `scripts/worktree.mjs`: importa `WORKTREE_VARIANT` (bloco L147-156); consumo via `resolveLaunchModel` L169-176 → `printLaunchDirective` L178-189; docblock/help citam mapa+variant em L22-29, L33-34, L39, L73, L88, L809, L811, L821, L824, L830, L842, L850; **resquício**: help L101 ainda diz "`--go` é no-op" (OPS24 — stale desde o remapeamento do OPS93).
|
||||
- `.agents/shell/worktree.sh`: L10, L15-19 (mapa + `--variant max`), L50 (`--go` mimo-v2.5).
|
||||
- `.opencode/commands/worktree.md`: L7 (mapa + "`--variant max` sempre"), L12 (diretiva com variant).
|
||||
- `.agents/skills/worktree-next-issue/SKILL.md`: L32, L34. `.agents/skills/local-database/SKILL.md`: L29.
|
||||
- `tests/unit/worktree.unit.spec.ts`: pins L160-218 (~10 expects com `'--variant ${WORKTREE_VARIANT}'` embutido), L195-204 (`expect(WORKTREE_VARIANT).toBe('max')`), L234-241 (`toEqual` do mapa), L251-256 (flags), L267-282 (diretiva por flag).
|
||||
- Consumidores do mapa: único `resolveWorktreeModel` (lib L62-71) ← `scripts/worktree.mjs:172`. Nada exporta `WORKTREE_VARIANT` para env/shell. `tests/unit/opencodeCommands.unit.spec.ts` não é afetado (anti-goal — não mexer).
|
||||
- Blast radius: `scripts/worktree.mjs` está em `HIGH_RISK_EXACT` (`scripts/lib/test-affected-core.mjs:36`; pin espelho `tests/unit/testAffected.unit.spec.ts:28`) → diff nele = unit/int full + e2e curado no PR. `scripts/lib/worktree.mjs` NÃO é high-risk.
|
||||
- Catálogo local (explorador): `opencode-go` tem `ox-alpha-free` ✓ `qwen3.7-max` ✓ `mimo-v2.5` ✓; `alibaba-token-plan` tem `qwen3.7-max` ✓; `cheapestinference` serve modelos pela config da máquina (`deepseek-v4-flash`, `mimo-v2.5`); **não existe** provider `opencode-zen` (gate da intenção confirmou `--zen` → `opencode-go/ox-alpha-free` — igual ao atual).
|
||||
|
||||
## Abordagem recomendada
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
PINS["tests/unit/worktree.unit.spec.ts\npins novos (sem variant, mapa GATE)"] --> LIB["scripts/lib/worktree.mjs\nmapa values + remove WORKTREE_VARIANT\ndiretiva L198 sem --variant"] LIB --> CLI["scripts/worktree.mjs\nimport/help/docblock"]
|
||||
CLI --> SURF[".agents/shell/worktree.sh\n.opencode/commands/worktree.md\n2 skills"]
|
||||
SURF --> GATES["pnpm test:unit -t worktree\npnpm gate:fast\nsmoke terminal"]
|
||||
```
|
||||
|
||||
**Opções consideradas:** A | B | C
|
||||
**Recomendação:** A — remoção incondicional de `--variant`/`WORKTREE_VARIANT` + troca dos **values** do mapa existente; assinaturas (`resolveWorktreeModel`, `opencodeLaunchDirective({dir,purpose,terminal,issueNumber,model})`), chaves de flags e preset intactos; 7 superfícies de texto sincronizadas num único lote. Cabe no appetite (~2 arquivos de lógica + 5 de doc/skill + 1 spec), não cria módulo novo (depth check: o dono do concern já existe), e a diretiva volta ao formato que o TUI aceita.
|
||||
|
||||
**Rejeitadas:**
|
||||
|
||||
- **B — emitir `--variant` condicionalmente** (só quando o modelo expuser variante): reintroduz o conceito que caiu com a premissa falsa do OPS93; exigiria catálogo de variants no repo (anti-goal: config global é assunto da máquina, OPS78/OPS89) e complexidade sem pedido. O "effort max" morre junto com a premissão — variantes seguem selecionáveis via Ctrl+T no TUI e `--variant max` segue vivo só no `opencode run` headless.
|
||||
- **C — reescrever a resolução de modelo** (nova função/módulo para o mapa): twinning do `resolveWorktreeModel`/`WORKTREE_MODEL_MAP` existentes; rejeitada — editar o dono do concern, não criar paralelo.
|
||||
|
||||
### Decisões de engenharia (com rejeitadas)
|
||||
|
||||
1. **Remoção incondicional do `--variant` na diretiva do TUI**
|
||||
- Opções: A) remover sempre | B) condicional ao modelo | C) mover variante para config do repo.
|
||||
- Recomendação: A — a quebra é incondicional (o TUI nunca aceita `--variant`); B/C reabrem o laboratório de variantes cortado pela intenção (rabbit hole nomeado).
|
||||
- Forma: args volta a `[dir,'--model',selectedModel,'--auto']` (+ `--prompt` quando houver); constante `WORKTREE_VARIANT` eliminada (export + import em `scripts/worktree.mjs` + todos os pins).
|
||||
|
||||
2. **Mapa-alvo (confirmado pelo humano no GATE de 2026-08-24; IDs validados contra o catálogo local)**
|
||||
|
||||
| Flag | Valor atual (OPS93 entregue) | Alvo (GATE) |
|
||||
| ----------- | ------------------------------------- | ------------------------------------------------ |
|
||||
| `--cheap` | `cheapestinference/deepseek-v4-flash` | `cheapestinference/deepseek-v4-flash` _(mantém)_ |
|
||||
| `--pro` | `opencode-go/qwen3.7-max` | `deepseek/deepseek-v4-pro` |
|
||||
| `--zen` | `opencode-go/ox-alpha-free` | `opencode-go/ox-alpha-free` _(mantém)_ |
|
||||
| `--go` | `opencode-go/mimo-v2.5` | `opencode-go/hy3` |
|
||||
| `--alibaba` | `alibaba-token-plan/qwen3.7-max` | `alibaba-token-plan/deepseek-v4-flash` |
|
||||
- Fecha a conta da intenção: três modelos corrigidos (`--pro`, `--go`, `--alibaba`) e um provider questionado (`--pro`: sai de `opencode-go`, vai ao provider `deepseek`); `--cheap`/`--zen` permanecem.
|
||||
- Restrição estrutural: só **values** mudam; chaves, `WORKTREE_MODEL_FLAGS` derivado e preset ficam intactos.
|
||||
- Validação de catálogo (feita): `deepseek/deepseek-v4-pro` ✓, `opencode-go/hy3` ✓, `alibaba-token-plan/deepseek-v4-flash` ✓, `cheapestinference/deepseek-v4-flash` ✓ (config da máquina), `opencode-go/ox-alpha-free` ✓.
|
||||
|
||||
3. **Sincronização das 7 superfícies + resquício do help**
|
||||
- As 7 da intenção: docblocks/mapa em `scripts/lib/worktree.mjs`, docblock/help em `scripts/worktree.mjs`, `.agents/shell/worktree.sh`, `.opencode/commands/worktree.md`, `.agents/skills/worktree-next-issue/SKILL.md`, `.agents/skills/local-database/SKILL.md`, pins de teste.
|
||||
- Inclui também o help L101 de `scripts/worktree.mjs` ("`--go` é no-op" — stale do OPS24 dentro do bloco de ajuda do `kill`): sai na mesma entrega porque é o mesmo contrato de mapa/divergência documental que a intenção manda encerrar (precedente OPS24: contrato documentado em todas as superfícies na mesma entrega). Textos citando `--variant max`/effort viram descrição do mapa sem variant; menção a variantes passa a apontar Ctrl+T/config global (fora do repo).
|
||||
- `.opencode/agent/designer-campanha-solla.md:64` e `design-vision.md:15` citam `opencode-go/mimo-v2.5` como fallback de visão — **fora do escopo** (não são parte do mapa/diretiva; nada quebra).
|
||||
|
||||
### Componentes / mudanças
|
||||
|
||||
- **`scripts/lib/worktree.mjs`**: values do `WORKTREE_MODEL_MAP` (tabela GATE); delete `WORKTREE_VARIANT` (L54-55); `opencodeLaunchDirective` L198 sem `--variant`; docblocks L40-41/L171-177 descrevendo o mapa novo e sem variant.
|
||||
- **`scripts/worktree.mjs`**: remover import/usos de `WORKTREE_VARIANT`; docblock (L22-39, L73, L88) e help (L809-850, incl. L101 do `kill`) atualizados.
|
||||
- **`.agents/shell/worktree.sh`**, **`.opencode/commands/worktree.md`**, **2 skills**: textos espelhos do mesmo contrato.
|
||||
- **`tests/unit/worktree.unit.spec.ts`**: remover pins de `WORKTREE_VARIANT`/`'--variant'`; nova pinagem da diretiva (`--model X --auto [--prompt …]`) e do mapa GATE; suite de flags/exclusividade intacta em estrutura.
|
||||
- **Migration:** sem migration — tooling pura. **Access/Consent:** N/A. **UI:** Impeccable A — sem superfície de produto.
|
||||
|
||||
## Fases verificáveis
|
||||
|
||||
1. **Pins primeiro (TDD)** — atualizar `tests/unit/worktree.unit.spec.ts` para o contrato-alvo (diretiva sem `--variant`, mapa GATE confirmado); rodar e ver vermelho. Quota ~25%.
|
||||
2. **Lib** — `scripts/lib/worktree.mjs`: mapa + remoção do variant + docblocks; unit verde. Quota ~25%.
|
||||
3. **CLI + superfícies** — `scripts/worktree.mjs` (import/help/docblock/incl. L101) + shell + command + 2 skills, num único lote de sincronização. Quota ~30%.
|
||||
4. **Gates + entrega** — `pnpm test:unit -t worktree`; `pnpm gate:fast`; smoke `TEQO_WORKTREE_TERMINAL=1 node scripts/worktree.mjs next --stay` (diretiva impressa sem `--variant`, modelo do flag escolhido; múltiplas flags continua falhando alto); changelog NOVA entrada `docs/changelog/<data>-ops95.md`; `pnpm push` → PR `Closes #876` (HIGH_RISK_EXACT dispara unit/int full + e2e curado no CI). Quota ~20%.
|
||||
|
||||
## Rabbit holes / Não escopo (engenharia)
|
||||
|
||||
- Reabrir o mapa além da tabela GATE (trocar `--cheap`/`--zen`, aceitar `provider/model` livre, cardápio novo).
|
||||
- Reintroduzir effort/variante por outra via (env por worktree, `opencode.json` do repo, config global via commit) — variantes vivem na máquina (Ctrl+T; `opencode run --variant max` para headless).
|
||||
- Mudar preset, chaves de flags, prompts ou pins de `tests/unit/opencodeCommands.unit.spec.ts`.
|
||||
- Editar planos/changelog históricos (OPS93 imutável; entrada nova em `docs/changelog/`).
|
||||
- Estender o cardápio ou aceitar `provider/model` livre.
|
||||
- `.opencode/agent/designer-campanha-solla.md` e `design-vision.md` citam `opencode-go/mimo-v2.5` como fallback de visão (fora do mapa/diretiva; nada quebra). **Deferido com gatilho:** atualizar na próxima troca de mapa de modelos ou edição desses docs (mesma classe de drift texto↔código desta entrega).
|
||||
|
||||
## Riscos e mitigação
|
||||
|
||||
- **HIGH_RISK_EXACT (`scripts/worktree.mjs`)** → PR roda unit/int full + e2e curado; mitigação: tocar só import/docblock/help, sem `provision`/claim/PORT/env.
|
||||
- **Divergência de contrato nas 7 superfícies de texto (+ resquício do help do kill)** → mitigação: lote único (Fase 3) + grep final por `--variant`/`WORKTREE_VARIANT`/valores antigos do mapa zerando fora de histórico imutável.
|
||||
- **Suíte herdar `OPENCODE_WORKTREE_MODEL`** (`presetInEffect()` lê env) → mitigação: manter padrão existente do spec; rodar unit no ambiente limpo do gate.
|
||||
- **ID do mapa GATE sumir do catálogo da máquina no futuro** → mitigação: IDs validados hoje; smoke imprime a diretiva e o uso real falha alto/visível — se um provider mudar, vira correção futura, não commit de catálogo.
|
||||
|
||||
## Aceite de engenharia
|
||||
|
||||
- [ ] Aceite de produto coberto: TUI abre sozinho nas invocações com/sem flag; 5 flags → mapa corrigido; sem flag → preset; fora do terminal inalterado; 7 superfícies sincronizadas.
|
||||
- [ ] Invariantes: sem collection/migration/PII/Consent; identificadores em inglês; sem ciclo; editado o dono do concern (sem twin).
|
||||
- [ ] Testes: unit pins do mapa + diretiva (TDD); `pnpm gate:fast` verde; smoke de terminal registrado no PR.
|
||||
|
||||
---
|
||||
|
||||
Self-score decision-quality: 5/5 — decisões caras com rejeitadas (remoção incondicional; values-only; sync única); cabe no appetite; rabbit holes nomeados (inventar mapa é bloqueado pelo GATE); reusa `WORKTREE_MODEL_MAP`/`resolveWorktreeModel`/`opencodeLaunchDirective` sem twinning; outcome da intenção preservado.
|
||||
|
|
@ -29,31 +29,33 @@ export const WORKTREE_TERMINAL_ENV = 'TEQO_WORKTREE_TERMINAL'
|
|||
* em 24/08/2026) e porque unificar o default reduz a sobrescrita confusa de
|
||||
* seleção de modelo do TUI (opencode issues #8349/#13456). OPS93: com
|
||||
* `--cheap/--pro/--zen/--go/--alibaba` o mapa `WORKTREE_MODEL_MAP` escolhe o
|
||||
* modelo por invocação; sem flag o preset permanece.
|
||||
* modelo por invocação; sem flag o preset permanece. OPS95: sem `--variant`
|
||||
* na diretiva (o TUI rejeita o flag) — variantes ficam na config global da
|
||||
* máquina, via Ctrl+T.
|
||||
*/
|
||||
export const OPENCODE_PRESET_MODEL =
|
||||
process.env.OPENCODE_WORKTREE_MODEL || 'deepseek/deepseek-v4-flash'
|
||||
|
||||
/**
|
||||
* Per-invocation model map — fixed menu of 5 named flags (OPS93). The
|
||||
* Per-invocation model map — fixed menu of 5 named flags (OPS93; values
|
||||
* corrected in OPS95 after the OPS93 delivery shipped wrong IDs). The
|
||||
* directive picks `WORKTREE_MODEL_MAP[flag]` when a single flag is present,
|
||||
* otherwise falls back to `OPENCODE_PRESET_MODEL`. Always launched with
|
||||
* `--variant max` (fail-high if the target model doesn't expose the variant).
|
||||
* otherwise falls back to `OPENCODE_PRESET_MODEL`. No `--variant` is emitted
|
||||
* (the TUI yargs rejects the flag — OPS95): variants live on the machine's
|
||||
* global config, selectable via Ctrl+T (`opencode run --variant max` remains
|
||||
* the headless path).
|
||||
*/
|
||||
export const WORKTREE_MODEL_MAP = {
|
||||
cheap: 'cheapestinference/deepseek-v4-flash',
|
||||
pro: 'opencode-go/qwen3.7-max',
|
||||
pro: 'deepseek/deepseek-v4-pro',
|
||||
zen: 'opencode-go/ox-alpha-free',
|
||||
go: 'opencode-go/mimo-v2.5',
|
||||
alibaba: 'alibaba-token-plan/qwen3.7-max',
|
||||
go: 'opencode-go/hy3',
|
||||
alibaba: 'alibaba-token-plan/deepseek-v4-flash',
|
||||
}
|
||||
|
||||
/** Set of flag names that select a model (keys of WORKTREE_MODEL_MAP). */
|
||||
export const WORKTREE_MODEL_FLAGS = new Set(Object.keys(WORKTREE_MODEL_MAP))
|
||||
|
||||
/** Variant always used for worktree launches — effort max (OPS78 guardrail). */
|
||||
export const WORKTREE_VARIANT = 'max'
|
||||
|
||||
/**
|
||||
* Resolve the model for a parsed `flags` bag (from `parseArgs`). At most one
|
||||
* model flag may be present — multiple → throw (fail-high, never guess).
|
||||
|
|
@ -172,8 +174,9 @@ const namespaceBranchName = ({ prefix, bag = '', taken = new Set(), fallback })
|
|||
* Launch directive for the opencode TUI, printed by `worktree next`/`plan`
|
||||
* right before the `cd <dir>` line when called from the interactive terminal
|
||||
* (`WORKTREE_TERMINAL=1`): `launch opencode <dir> --model <preset|map>
|
||||
* --variant max --auto [--prompt "<command>"]` (OPS93: `--variant max` sempre;
|
||||
* modelo vem do mapa `WORKTREE_MODEL_MAP` quando a flag `--cheap/--pro/--zen/
|
||||
* --auto [--prompt "<command>"]` (OPS95: no `--variant` — the TUI yargs
|
||||
* rejects the unknown flag and the helper prints instead of opening; modelo
|
||||
* vem do mapa `WORKTREE_MODEL_MAP` quando a flag `--cheap/--pro/--zen/
|
||||
* --go/--alibaba` está presente, senão do preset). The shell function
|
||||
* (`.agents/shell/worktree.sh`) applies the `cd` first, then tokenizes and
|
||||
* executes this line (xargs — quote-aware, never eval) — the dir is always
|
||||
|
|
@ -195,7 +198,7 @@ export const opencodeLaunchDirective = ({
|
|||
if (!terminal) return null
|
||||
const prompt = OPENCODE_SKILL_COMMAND_BY_PURPOSE[purpose]
|
||||
const selectedModel = model ?? OPENCODE_PRESET_MODEL
|
||||
const args = [dir, '--model', selectedModel, '--variant', WORKTREE_VARIANT, '--auto']
|
||||
const args = [dir, '--model', selectedModel, '--auto']
|
||||
if (prompt) {
|
||||
// The issue suffix belongs to `next` alone — `plan`/`new` never carry a
|
||||
// claimed issue (fail-safe: a stray issueNumber must not break /plan-issue).
|
||||
|
|
|
|||
|
|
@ -22,22 +22,25 @@
|
|||
* acontece); `--cheap/--pro/--zen/--go/--alibaba`
|
||||
* escolhe o modelo por invocação no mapa fixo
|
||||
* `WORKTREE_MODEL_MAP` (cheap=cheapestinference/
|
||||
* deepseek-v4-flash, pro=opencode-go/qwen3.7-max,
|
||||
* deepseek-v4-flash, pro=deepseek/deepseek-v4-pro,
|
||||
* zen=opencode-go/ox-alpha-free, go=opencode-go/
|
||||
* mimo-v2.5, alibaba=alibaba-token-plan/qwen3.7-max)
|
||||
* com `--variant max` sempre (OPS93; sem flag o
|
||||
* preset `deepseek/deepseek-v4-flash` permanece).
|
||||
* hy3, alibaba=alibaba-token-plan/deepseek-v4-flash;
|
||||
* OPS95) — sem flag o preset
|
||||
* `deepseek/deepseek-v4-flash` permanece.
|
||||
* Chamado do terminal interativo (com
|
||||
* `TEQO_WORKTREE_TERMINAL=1`, que só a função shell
|
||||
* seta), imprime também a diretiva `launch
|
||||
* opencode <dir> --model <preset|map> --variant max
|
||||
* opencode <dir> --model <preset|map>
|
||||
* --auto --prompt "/work-issue --issue <N>"` ANTES
|
||||
* do `cd` — a função shell executa o cd e então a
|
||||
* linha, e o TUI do opencode abre no worktree com
|
||||
* `/work-issue --issue <N>` já enviado (OPS26 +
|
||||
* OPS33: o launch entrega a Issue claimada ao
|
||||
* agente; a skill lê o resto do GitHub) em effort
|
||||
* max. Presets e mapa em scripts/lib/worktree.mjs.
|
||||
* agente; a skill lê o resto do GitHub). OPS95:
|
||||
* sem `--variant` na diretiva — o yargs do TUI
|
||||
* rejeita o flag e só imprime o helper; variantes
|
||||
* ficam na config global da máquina (Ctrl+T).
|
||||
* Presets e mapa em scripts/lib/worktree.mjs.
|
||||
* Sem o marcador (comando `/worktree` do opencode),
|
||||
* a diretiva não é impressa — nunca abre TUI aninhado.
|
||||
* Também PROVISIONA o ambiente isolado do worktree:
|
||||
|
|
@ -70,8 +73,8 @@
|
|||
* terminal, mesma diretiva `launch` — com
|
||||
* `--prompt /plan-issue` já enviado (OPS31: o TUI
|
||||
* abre no fluxo de planejamento, sem digitação) e
|
||||
* `--model <map> --variant max` quando a flag de
|
||||
* modelo está presente.
|
||||
* `--model <map>` quando a flag de modelo está
|
||||
* presente.
|
||||
* pnpm worktree new [bag] [--stay] [--no-migrate] [--cheap|--pro|--zen|--go|--alibaba]
|
||||
* cria um worktree NEUTRO novo — sem função
|
||||
* pré-definida (explorar ideia, conversar, ou
|
||||
|
|
@ -85,8 +88,8 @@
|
|||
* Mesmo provisionamento isolado do `next`/`plan`;
|
||||
* no terminal, mesma diretiva `launch` — SEM
|
||||
* `--prompt` (apenas conversar, nenhuma skill) e
|
||||
* `--model <map> --variant max` quando a flag de
|
||||
* modelo está presente.
|
||||
* `--model <map>` quando a flag de modelo está
|
||||
* presente.
|
||||
* `--stay` suprime a linha `cd` e a diretiva;
|
||||
* `--cheap/--pro/--zen/--go/--alibaba` escolhe o
|
||||
* modelo por invocação (sem flag o preset permanece).
|
||||
|
|
@ -98,7 +101,8 @@
|
|||
* padrão termina imprimindo `cd <main>` para o
|
||||
* shell voltar ao worktree principal — o cwd nunca
|
||||
* fica num diretório destruído (não aceita
|
||||
* `--stay`; `--go` é no-op)
|
||||
* `--stay`; sem launch, as flags de modelo são
|
||||
* irrelevantes)
|
||||
*
|
||||
* Read-only no GitHub? NÃO — desde o OPS33 `next` CLAIMA: claim determinístico
|
||||
* antes do worktree (mesma fila/ordem e lock otimista do `pnpm agent:claim`;
|
||||
|
|
@ -151,8 +155,9 @@ import {
|
|||
planBranchName,
|
||||
resolveWorktreeModel,
|
||||
workBranchName,
|
||||
WORKTREE_MODEL_FLAGS,
|
||||
WORKTREE_MODEL_MAP,
|
||||
WORKTREE_TERMINAL_ENV,
|
||||
WORKTREE_VARIANT,
|
||||
} from './lib/worktree.mjs'
|
||||
|
||||
const die = dieAgent('worktree')
|
||||
|
|
@ -818,10 +823,14 @@ 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 <dir> --model <preset|map> --variant max --auto --prompt "/work-issue --issue <N>"` (OPS26+OPS33+OPS93:',
|
||||
' `launch opencode <dir> --model <preset|map> --auto --prompt "/work-issue --issue <N>"` (OPS26+OPS33+OPS93+OPS95:',
|
||||
)
|
||||
console.log(
|
||||
` abre o TUI com ${OPENCODE_PRESET_MODEL} (sem flag) ou com o mapa --cheap=cheapestinference/deepseek-v4-flash --pro=opencode-go/qwen3.7-max --zen=opencode-go/ox-alpha-free --go=opencode-go/mimo-v2.5 --alibaba=alibaba-token-plan/qwen3.7-max (todos --variant ${WORKTREE_VARIANT}) + auto + a Issue claimada já`,
|
||||
` abre o TUI com ${OPENCODE_PRESET_MODEL} (sem flag) ou com o mapa ${[
|
||||
...WORKTREE_MODEL_FLAGS,
|
||||
]
|
||||
.map((flag) => `--${flag}=${WORKTREE_MODEL_MAP[flag]}`)
|
||||
.join(' ')} + auto + a Issue claimada já`,
|
||||
)
|
||||
console.log(
|
||||
' informada); --stay suprime cd e launch (o claim ainda acontece); --no-migrate pula migrations e o',
|
||||
|
|
@ -839,7 +848,7 @@ if (!subcommand) {
|
|||
' minúsculo plans/… nunca colide com o branch <code>-<slug> de `next`; no terminal,',
|
||||
)
|
||||
console.log(
|
||||
' mesma diretiva `launch` com --prompt /plan-issue enviado (abre no fluxo de planejamento, sem digitação) e --model <map> --variant max quando a flag está presente',
|
||||
' mesma diretiva `launch` com --prompt /plan-issue enviado (abre no fluxo de planejamento, sem digitação) e --model <map> quando a flag está presente',
|
||||
)
|
||||
console.log(`\n new [bag] [--stay] [--no-migrate] [--cheap|--pro|--zen|--go|--alibaba]`)
|
||||
console.log(' cria um worktree NEUTRO (sem função pré-definida) DIFERENTE a cada invocação:')
|
||||
|
|
@ -847,7 +856,7 @@ if (!subcommand) {
|
|||
console.log(' próximo work/<n> sequencial livre; o prefixo minúsculo work/… nunca colide com')
|
||||
console.log(' o branch <code>-<slug> de `next` nem com plans/plan-issue-… de `plan`; no')
|
||||
console.log(
|
||||
' terminal, mesma diretiva `launch` porém sem --prompt (apenas conversar) e --model <map> --variant max quando a flag está presente',
|
||||
' terminal, mesma diretiva `launch` porém sem --prompt (apenas conversar) e --model <map> quando a flag está presente',
|
||||
)
|
||||
console.log(' kill [--force] destrói o worktree em que você está (recusa sujo sem --force),')
|
||||
console.log(' remove os bancos gerados do worktree (best-effort) e imprime')
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import {
|
|||
WORKTREE_MODEL_FLAGS,
|
||||
WORKTREE_MODEL_MAP,
|
||||
WORKTREE_TERMINAL_ENV,
|
||||
WORKTREE_VARIANT,
|
||||
} from '../../scripts/lib/worktree.mjs'
|
||||
|
||||
type TestIssue = {
|
||||
|
|
@ -146,7 +145,7 @@ describe('planBranchName (per-invocation planning worktrees)', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33 + OPS93)', () => {
|
||||
describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33 + OPS93 + OPS95)', () => {
|
||||
const dir = '/home/fsolla/.cursor/worktrees/teqo/OPS26-foo'
|
||||
|
||||
it('returns null outside the terminal — the /worktree command never launches a TUI', () => {
|
||||
|
|
@ -157,9 +156,9 @@ describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33
|
|||
).toBeNull()
|
||||
})
|
||||
|
||||
it('next launches with the preset model, --variant max, --auto and the /work-issue command sent (value always quoted)', () => {
|
||||
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 ${presetInEffect()} --variant ${WORKTREE_VARIANT} --auto --prompt "/work-issue"`,
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --auto --prompt "/work-issue"`,
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -167,35 +166,34 @@ describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33
|
|||
expect(
|
||||
opencodeLaunchDirective({ dir, purpose: 'next', terminal: true, issueNumber: 595 }),
|
||||
).toBe(
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --variant ${WORKTREE_VARIANT} --auto --prompt "/work-issue --issue 595"`,
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --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 ${presetInEffect()} --variant ${WORKTREE_VARIANT} --auto --prompt "/plan-issue"`,
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --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 ${presetInEffect()} --variant ${WORKTREE_VARIANT} --auto`,
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --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 ${presetInEffect()} --variant ${WORKTREE_VARIANT} --auto --prompt "/plan-issue"`,
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --auto --prompt "/plan-issue"`,
|
||||
)
|
||||
expect(opencodeLaunchDirective({ dir, purpose: 'new', terminal: true, issueNumber: 7 })).toBe(
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --variant ${WORKTREE_VARIANT} --auto`,
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --auto`,
|
||||
)
|
||||
})
|
||||
|
||||
it('pins the preset constants — fallback comum deepseek-v4-flash, override via OPENCODE_WORKTREE_MODEL', () => {
|
||||
expect(OPENCODE_PRESET_MODEL).toBe(presetInEffect())
|
||||
expect(WORKTREE_TERMINAL_ENV).toBe('TEQO_WORKTREE_TERMINAL')
|
||||
expect(WORKTREE_VARIANT).toBe('max')
|
||||
expect(OPENCODE_SKILL_COMMAND_BY_PURPOSE).toEqual({
|
||||
next: '/work-issue',
|
||||
plan: '/plan-issue',
|
||||
|
|
@ -205,14 +203,23 @@ 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 ${presetInEffect()} --variant ${WORKTREE_VARIANT} --auto`,
|
||||
`launch opencode ${dir} --model ${presetInEffect()} --auto`,
|
||||
)
|
||||
})
|
||||
|
||||
it('uses the explicit model when provided (OPS93 map) — always with --variant max', () => {
|
||||
it('never emits --variant — the TUI yargs rejects it (OPS95); variants live on machine config (Ctrl+T)', () => {
|
||||
for (const model of Object.values(WORKTREE_MODEL_MAP)) {
|
||||
for (const purpose of ['next', 'plan', 'new']) {
|
||||
const directive = opencodeLaunchDirective({ dir, purpose, terminal: true, model })
|
||||
expect(directive).not.toContain('--variant')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('uses the explicit model when provided (OPS93 map, OPS95 values)', () => {
|
||||
for (const [, model] of Object.entries(WORKTREE_MODEL_MAP)) {
|
||||
expect(opencodeLaunchDirective({ dir, purpose: 'next', terminal: true, model })).toBe(
|
||||
`launch opencode ${dir} --model ${model} --variant ${WORKTREE_VARIANT} --auto --prompt "/work-issue"`,
|
||||
`launch opencode ${dir} --model ${model} --auto --prompt "/work-issue"`,
|
||||
)
|
||||
}
|
||||
})
|
||||
|
|
@ -229,17 +236,16 @@ describe('opencodeLaunchDirective (terminal-only opencode launch, OPS26 + OPS33
|
|||
})
|
||||
})
|
||||
|
||||
describe('resolveWorktreeModel + WORKTREE_MODEL_MAP (OPS93)', () => {
|
||||
describe('resolveWorktreeModel + WORKTREE_MODEL_MAP (OPS93 menu, OPS95 values)', () => {
|
||||
it('pins the 5-flag map — cheap/pro/zen/go/alibaba', () => {
|
||||
expect(WORKTREE_MODEL_MAP).toEqual({
|
||||
cheap: 'cheapestinference/deepseek-v4-flash',
|
||||
pro: 'opencode-go/qwen3.7-max',
|
||||
pro: 'deepseek/deepseek-v4-pro',
|
||||
zen: 'opencode-go/ox-alpha-free',
|
||||
go: 'opencode-go/mimo-v2.5',
|
||||
alibaba: 'alibaba-token-plan/qwen3.7-max',
|
||||
go: 'opencode-go/hy3',
|
||||
alibaba: 'alibaba-token-plan/deepseek-v4-flash',
|
||||
})
|
||||
expect(WORKTREE_MODEL_FLAGS).toEqual(new Set(['cheap', 'pro', 'zen', 'go', 'alibaba']))
|
||||
expect(WORKTREE_VARIANT).toBe('max')
|
||||
})
|
||||
|
||||
it('no flag → preset', () => {
|
||||
|
|
@ -264,20 +270,20 @@ describe('resolveWorktreeModel + WORKTREE_MODEL_MAP (OPS93)', () => {
|
|||
)
|
||||
})
|
||||
|
||||
it('each flag launches with --variant max in the directive (next/plan/new share the path)', () => {
|
||||
it('each flag launches with the mapped model in the directive (next/plan/new share the path)', () => {
|
||||
const dir = '/tmp/wt'
|
||||
for (const [flag, model] of Object.entries(WORKTREE_MODEL_MAP)) {
|
||||
const resolved = resolveWorktreeModel({ [flag]: true })
|
||||
expect(resolved).toBe(model)
|
||||
expect(
|
||||
opencodeLaunchDirective({ dir, purpose: 'next', terminal: true, model: resolved }),
|
||||
).toContain(`--model ${model} --variant ${WORKTREE_VARIANT} --auto`)
|
||||
).toContain(`--model ${model} --auto`)
|
||||
expect(
|
||||
opencodeLaunchDirective({ dir, purpose: 'plan', terminal: true, model: resolved }),
|
||||
).toContain(`--model ${model} --variant ${WORKTREE_VARIANT} --auto`)
|
||||
).toContain(`--model ${model} --auto`)
|
||||
expect(
|
||||
opencodeLaunchDirective({ dir, purpose: 'new', terminal: true, model: resolved }),
|
||||
).toContain(`--model ${model} --variant ${WORKTREE_VARIANT} --auto`)
|
||||
).toContain(`--model ${model} --auto`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue