teqo-backup/docs/plans/opencode-comandos-work-issue-e-plan-issue-impl.md
Francisco Solla 7a4279b281 feat(OPS25): comandos opencode /work-issue e /plan-issue como atalhos diretos às skills
Dois comandos novos (.opencode/commands/) que instruem o agente a
carregar a skill de mesmo nome pela ferramenta de skills e seguir o
fluxo dela ponta a ponta, com $ARGUMENTS repassado. Frontmatter com
description (autocomplete do TUI) e model deepseek/deepseek-v4-flash
(alinhado ao launch da OPS26). Guard unit pina o acoplamento
comando↔skill para renomes não quebrarem silenciosamente.
2026-08-10 10:25:26 -03:00

6.6 KiB

Impl: OpenCode: comandos /work-issue e /plan-issue (atalho direto para as skills)

Status: aprovado Atualizado em: 2026-08-10 Issue: #570 Intenção: docs/plans/opencode-comandos-work-issue-e-plan-issue.md Appetite restante: herdado (~0,5 dia eng) — não estoura

Leitura da intenção

  • Outcome: digitar /work-issue ou /plan-issue no TUI do opencode dispara, com zero fricção, a skill de mesmo nome — carregada pela ferramenta de skills, seguida ponta a ponta, com $ARGUMENTS repassado; os comandos aparecem no autocomplete.
  • O que NÃO negociar: o corpo do comando não transcreve a skill (fonte canônica é .agents/skills/); não existe terceiro fluxo de planejamento; só as duas skills pedidas ganham comando.
  • O que reavaliar: a hipótese de model: no frontmatter (ver decisão 1) e se o comando deve fixar agent (ver decisão 2) — ambas já direcionadas pela intenção, confirmadas contra a fonte oficial do opencode.

Abordagem recomendada

flowchart LR
  A[Usuário digita /work-issue ou /plan-issue] --> B[opencode expande .opencode/commands/<nome>.md]
  B --> C[Frontmatter: description p/ autocomplete + model deepseek/deepseek-v4-flash]
  C --> D[Corpo: instrução curta — carregar skill pelo nome exato via ferramenta de skills]
  D --> E[$ARGUMENTS repassados no fim]
  E --> F[Agente carrega .agents/skills/<nome>/SKILL.md e segue o fluxo ponta a ponta]

Opções consideradas: A | B | C Recomendação: A — dois arquivos markdown em .opencode/commands/ seguindo o mecanismo nativo de commands (mesmo precedente de issue.md/worktree.md), frontmatter description + model, corpo de instrução sem transcrição, $ARGUMENTS no fim. Porque é o único caminho que usa o mecanismo do produto (autocomplete no TUI vem do frontmatter description) sem criar infra paralela.

Decisões de engenharia

1. model: no frontmatter dos comandos?

  • Opções: A) deepseek/deepseek-v4-flash nos dois | B) herdar o modelo da sessão.
  • Recomendação: A — o OPS26 já lança o opencode com --model deepseek/deepseek-v4-flash e /work-issue como primeira mensagem; o atalho manual deve produzir a mesma sessão de modelo de preferência. model é frontmatter documentado do opencode (formato provider/model). O pool roda em Cursor, não no TUI do opencode — o pin não conflita com o model: da Issue.
  • Rejeitada: B porque a sessão herdaria o último modelo usado, e o launch automático e o atalho manual divergiriam.

2. agent no frontmatter?

  • Opções: A) não fixar (usa o agente da sessão) | B) fixar build.
  • Recomendação: A — o fluxo de work-issue exige pausa para confirmação humana e deliberação (Plan mode), que vivem no agente da sessão; fixar build quebraria o gate humano e plan-issue tem gate próprio. agent é opcional e defaults para o agente da sessão.
  • Rejeitada: B porque o atalho não deve escolher o agente — a skill decide o modo.

3. Como guardar o acoplamento nome-comando ↔ nome-skill?

  • Opções: A) teste unit leve que pina os dois nomes | B) confiar em convenção (nomes amarrados "na mão").
  • Recomendação: A — spec novo tests/unit/opencodeCommands.unit.spec.ts (sem DB, síncrono, barato): para cada comando novo, existe o arquivo, o frontmatter tem description e model: deepseek/deepseek-v4-flash, o corpo referencia o nome exato da skill e .agents/skills/<nome>/SKILL.md existe. Renomear uma skill → build falha → renomear o comando junto.
  • Rejeitada: B porque o risco da intenção ("renomeou a skill, o comando quebra silencioso") é exatamente o que um teste de 20 linhas elimina.

Componentes / mudanças

  • .opencode/commands/work-issue.md (novo): frontmatter description (pt-BR, autocomplete) + model: deepseek/deepseek-v4-flash; corpo instruindo carregar a skill work-issue pela ferramenta de skills e segui-la ponta a ponta; $ARGUMENTS no fim.
  • .opencode/commands/plan-issue.md (novo): idem, referenciando a skill plan-issue.
  • tests/unit/opencodeCommands.unit.spec.ts (novo): guard de acoplamento (decisão 3).
  • Migration: sem migration (nada de schema).
  • Access / Consent: N/A — arquivos de configuração do opencode.
  • UI: Impeccable A — N/A (sem UI de produto).

Formato do comando (exemplo)

---
description: <descrição curta em pt-BR para o autocomplete>
model: deepseek/deepseek-v4-flash
---

Carregue a skill `<nome>` (ferramenta de skills, nome exato) e siga o fluxo dela de ponta a ponta. A fonte canônica é `.agents/skills/<nome>/SKILL.md` — não a transcreva nem recrie o fluxo.

$ARGUMENTS

Fases verificáveis

  1. Comandos — criar .opencode/commands/work-issue.md e plan-issue.md (frontmatter + corpo + $ARGUMENTS); sem tocar em issue.md/worktree.md nem em opencode.json.
  2. Guard de acoplamento — tests/unit/opencodeCommands.unit.spec.ts (frontmatter, nome da skill, $ARGUMENTS, existência da skill referenciada).
  3. Gates — pnpm gate:fast (inclui prettier — .opencode/ não está no .prettierignore —, lint, tsc, testes); pnpm push; PR Ready --base main com Closes #570 + auto-merge.

Verificação manual pós-merge (pelo humano, não em CI): /work-issue e /plan-issue no autocomplete do TUI.

Rabbit holes / Não escopo (engenharia)

  • Um comando por skill do repo (só as duas; o padrão fica provado pelo par).
  • Transcrever o corpo das skills dentro do comando (duplicação cara de manter).
  • Validar o TUI em CI (autocomplete é comportamento do produto, não testável headless aqui).
  • subtask/plugins/opencode.json — nada disso é necessário.

Riscos e mitigação

  • Diferença de versão do opencode no parsing do frontmatter: mitigado usando só chaves documentadas (description, model) — verificadas na fonte oficial (opencode.ai/docs/commands, atualizada 2026-08-09).
  • Renome de skill quebra o comando silenciosamente: mitigado pelo guard unit (decisão 3) — o build falha junto.
  • model: no frontmatter sobrescreve o modelo da sessão: é o comportamento desejado (OPS26 alinhado); documentado na decisão 1.
  • Prettier rejeitar o frontmatter YAML: mitigado escrevendo frontmatter mínimo no estilo dos arquivos existentes e rodando pnpm format:check na fase 3.

Aceite de engenharia

  • Aceite de produto da intenção ainda coberto (atalho direto às duas skills, sem transcrição, $ARGUMENTS repassado, autocomplete)
  • Invariantes AGENTS/engineering-standards (sem DB, sem schema, sem PII — arquivos de config)
  • Testes previstos: tests/unit/opencodeCommands.unit.spec.ts (guard de acoplamento)