Merge pull request #576 from fsolla/plans/plan-issue-22

docs(plan): lote OPS24-OPS27 — worktree CLI + comandos opencode
This commit is contained in:
Francisco Solla 2026-08-10 09:14:04 -03:00 committed by GitHub
commit 38e8beffba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 277 additions and 0 deletions

View file

@ -0,0 +1,67 @@
# OpenCode: comandos `/work-issue` e `/plan-issue` (atalho direto para as skills)
Status: rascunho
Atualizado em: 2026-08-10
Issue: #570
Priority: P2
Model: composer-2.5
model-local: deepseek-v4-flash-high
Impeccable: A — N/A (arquivos de configuração do opencode; sem UI de produto)
Canvas UI: N/A — sem UI
Appetite: ~0,5 dia eng; um outcome verificável (duas skills com um `/` de distância)
## Intenção
Toda sessão de trabalho no repo começa invocando `/work-issue` (executar uma Issue) ou `/plan-issue` (planejar um lote de ideias). O caminho atual é `/skills` → buscar a skill → enviar — três passos e uma busca que às vezes erra o nome. O opencode já suporta **commands** (`.opencode/commands/<nome>.md`): o template vira o prompt da sessão quando o usuário digita `/nome`. O repo já usa esse mecanismo (`/issue`, `/worktree`). Queremos `/work-issue` e `/plan-issue` como atalhos diretos que instruem o agente a carregar a skill pelo nome e seguir o fluxo dela de ponta a ponta.
## Persona e fluxo
- **Persona / contexto:** Francisco no TUI do opencode, começando uma sessão de execução ou de planejamento.
- **Job principal:** disparar a skill certa com zero fricção e com o modelo de preferência já selecionado.
- **Fluxo desejado:** digitar `/work-issue <args>` → o agente carrega a skill `work-issue` (via ferramenta de skills) e segue o ciclo completo (claim → plano de implementação → pausa humana → execução → `/simplify` → capture-review-debts → PR); `/plan-issue <args>` idem para o ciclo de intenção (parse → planos → gate → registro). Argumentos repassados via `$ARGUMENTS`.
- **Anti-goals de produto:** não transcrever o corpo das skills dentro do comando (a fonte canônica continua `.agents/skills/`); não criar um terceiro fluxo paralelo de planejamento.
## Objetivo e aceite
- `/work-issue` e `/plan-issue` aparecem no autocomplete do TUI e funcionam em qualquer diretório do repo (projeto opencode).
- O template instrui o agente a carregar a skill pelo nome exato e seguir o fluxo dela ponta a ponta, sem reescrever o conteúdo.
- `$ARGUMENTS` é repassado (ex.: `/plan-issue <lote>`).
- Cada comando leva `model: deepseek/deepseek-v4-flash` no frontmatter — sessão manual já abre no modelo de preferência (ver questão em aberto).
- Abertura automática a partir de `worktree next/plan` (OPS26) usa estes comandos como primeira mensagem.
## Dados (intenção)
- **Vou apresentar dados?** Não — sem superfície de dados.
## Direção no codebase (hipótese)
- **Áreas prováveis:** `.opencode/commands/work-issue.md` e `.opencode/commands/plan-issue.md` (novos; precedente: `issue.md` e `worktree.md` já existem); frontmatter `description` + `model`; corpo com instrução curta de "carregue a skill X e siga-a", com `$ARGUMENTS` no fim.
- **Precedente a olhar:** `.opencode/commands/worktree.md` (formato frontmatter + corpo + `!` bash); `.agents/skills/work-issue/SKILL.md` e `plan-issue/SKILL.md` (nomes exatos a referenciar).
- **Risco de acoplamento:** o nome do comando casa com o nome da skill (`/work-issue` ↔ skill `work-issue`) — se uma skill for renomeada, o comando quebra silenciosamente; manter nomes amarrados.
## Dependências
- Nenhuma. (Pré-requisito do fluxo de launch da OPS26.)
## Fora de escopo
- Alterar o conteúdo das skills `work-issue`/`plan-issue`.
- O launch automático do opencode a partir do CLI `worktree` — item próprio (OPS26).
- Comandos para outras skills (só as duas pedidas; qualquer outra segue o mesmo padrão quando alguém quiser).
## Rabbit holes de produto
- **"Um comando por skill do repo":** escopo explode para uma fileira de arquivos de comando. **Corte neste item:** só `work-issue` e `plan-issue`; o padrão fica documentado pelo par.
- **"Template do comando = skill copiada":** duplicação cara de manter — o comando referencia a skill pelo nome, não a reproduz.
## Questões em aberto (produto)
- **`model:` no frontmatter dos comandos?** **Opções:** A) `deepseek/deepseek-v4-flash` nos dois — sessão manual já abre no modelo de preferência, e o launch da OPS26 não precisaria do flag | B) herdar o modelo da sessão. **Recomendação:** A — é exatamente o "pré-selecionado" que o usuário pediu para o launch; por consistência, o atalho manual deve fazer o mesmo. _(assumido — validar no gate)_
- **Comando `work-issue` também define `agent`?** **Opções:** A) não (usa o agente da sessão) | B) fixar `build`. **Recomendação:** A — o ciclo da skill decide o agente, não o atalho.
## Referências
- GitHub Issue #570
- `.opencode/commands/worktree.md` e `.opencode/commands/issue.md` — precedentes do formato
- `.agents/skills/work-issue/SKILL.md`, `.agents/skills/plan-issue/SKILL.md` — nomes e fluxos a referenciar
- Docs opencode: https://opencode.ai/docs/commands — frontmatter (`description`, `model`, `agent`) e `$ARGUMENTS`

View file

@ -0,0 +1,70 @@
# Worktree `go` abre o opencode com pré-seleções (DeepSeek V4 Flash, auto-approve, skill inicial)
Status: rascunho
Atualizado em: 2026-08-10
Issue: #571
Priority: P2
Model: composer-2.5
model-local: deepseek-v4-flash-high
Impeccable: A — N/A (CLI de dev; sem UI de produto)
Canvas UI: N/A — sem UI
Appetite: ~0,5–1 dia eng; um outcome verificável (do terminal ao TUI do opencode sem tocar em nada)
## Intenção
Depois de criar um worktree, o fluxo natural é trabalhar nele com o opencode — e hoje isso são três gestos manuais: `cd` (com `--go`), `opencode` no diretório e `/skills` → buscar `work-issue` → enviar. O opencode já oferece as pré-seleções via CLI: `opencode <dir> --model <provider/model> --auto --prompt "<msg>"` abre o TUI no diretório com modelo escolhido, permissões em auto-approve e a mensagem já enviada — e **verificamos na fonte** que uma mensagem inicial que começa com `/` expande para o comando (`submit()` → `session.command`). Então `opencode <worktree> --model deepseek/deepseek-v4-flash --auto --prompt "/work-issue"` abre exatamente a sessão desejada. Queremos que `worktree next` (go, default desde OPS24) termine nessa sessão.
## Persona e fluxo
- **Persona / contexto:** Francisco no terminal (função `worktree()` do `.agents/shell/worktree.sh`), fluxo diário de abrir worktree para executar ou planejar.
- **Job principal:** ir da linha de comando para uma sessão de opencode pronta (modelo certo + permissões + skill certa) com um único comando.
- **Fluxo desejado:** `worktree next` → cria/provisiona → `cd` → abre o TUI do opencode no worktree com `deepseek/deepseek-v4-flash`, auto-approve ativo e primeira mensagem `/work-issue` **enviada** (que expande o comando da OPS25). `worktree plan` → mesma abertura, com `/plan-issue` **pré-preenchido no input, sem enviar** (hoje: sem prompt, autocomplete completa — ver aceite). `--stay` (OPS24) suprime o launch.
- **Anti-goals de produto:** não abrir TUI aninhado quando o comando roda de dentro do opencode (`/worktree`); não alterar o provisionamento; não hardcodar presets por worktree (arquivos de config commitados).
## Objetivo e aceite
- No terminal, `worktree next` termina com o TUI do opencode aberto no worktree: modelo `deepseek/deepseek-v4-flash` selecionado, permissões em auto-approve (`--auto`) e a mensagem `/work-issue` **já enviada** — não apenas pré-preenchida (o comando da OPS25 executa o ciclo).
- `worktree plan` abre o opencode com os mesmos presets e o input **pré-preenchido com `/plan-issue` mas sem enviar** — o humano decide quando disparar. **Restrição descoberta na verificação:** a CLI atual do opencode só sabe preencher o input com `--prompt`, e esse caminho **sempre auto-envia** (o TUI chama `submit()`; não há flag de pre-fill sem submit — `route.prompt` existe no tipo da rota mas não é populável via CLI). Fallback acordado: `plan` abre **sem** prompt — o usuário digita `/plan-` e o autocomplete do TUI completa. Se a CLI ganhar pre-fill sem submit, `plan` passa a usá-lo.
- Quando o script roda **sem** o marcador de terminal (comando `/worktree` do opencode, automação), o launch **não** acontece — só o `cd` (comportamento atual preservado; sem TUI dentro de TUI).
- `--stay` (OPS24) suprime cd e launch.
- Ao sair do opencode, o shell retorna ao terminal no worktree (launch sem `exec`) — e **não** há execução automática de `worktree kill` ao sair (o worktree continua vivo para a próxima sessão).
- Presets (modelo/auto) são constantes declaradas no script — trocar de modelo é editar uma constante, não caçar flags espalhadas.
## Dados (intenção)
- **Vou apresentar dados?** Não.
## Direção no codebase (hipótese)
- **Áreas prováveis:** `scripts/worktree.mjs` (novo bloco de "launch directive": quando chamado com env/flag que só a função shell passa — ex. `WORKTREE_TERMINAL=1` — imprime a linha `opencode <dir> --model deepseek/deepseek-v4-flash --auto --prompt /work-issue` após o `cd`); `.agents/shell/worktree.sh` (chama o script com o marcador e executa as duas linhas); `.opencode/commands/worktree.md` (roda sem marcador — nada muda além do texto).
- **Precedente a olhar:** o contrato `cd <dir>` na última linha já existe; o opencode command não precisa saber do launch.
- **Risco de acoplamento:** o marcador de terminal é o que separa o comportamento em duas superfícies — sem ele, o `/worktree` do opencode abriria um TUI aninhado. A skill/AGENTS.md devem documentar que `next`/`plan` **no terminal** abrem o opencode.
## Dependências
- OPS24 (semântica `--go` default / `--stay` — o launch vive no mesmo caminho de "go").
- OPS25 (comandos `/work-issue` e `/plan-issue` — a primeira mensagem do launch os invoca).
## Fora de escopo
- O subcomando `worktree new` — item próprio (OPS27; herda o launch sem skill inicial).
- Config global de opencode (`~/.config/opencode/opencode.json`) — presets são por-invocação via flags, não config persistente.
- Escolher o modelo de forma dinâmica (ex.: perguntar ao usuário) — constante fixa no script, configurável por edição.
## Rabbit holes de produto
- **"Configurar o worktree com um `opencode.json` próprio":** arquivos commitados no repo virariam config de todo mundo. **Corte:** flags na linha de comando, efêmeras.
- **"`--auto` é perigoso":** sim — é exatamente o que o usuário pediu ("Enable auto-approve permissions"); o `--auto` só vale para a sessão lançada, não muda a config global. Deixar a escolha documentada no plano de implementação.
## Questões em aberto (produto)
- **`plan` sem pre-fill (fallback) é aceitável?** **Opções:** A) sim — `plan` abre sem prompt; `/plan-` + autocomplete completa (recomendado; única forma hoje) | B) `plan` envia `/plan-issue` igual ao `next` (contradiz a preferência de não enviar) | C) `plan` não abre opencode (só cd). **Recomendação:** A — o autocomplete do TUI completa `/plan-issue` com pouquíssimos toques, e não dispara nada sem o Enter do humano. _(confirmado no gate — restrição de plataforma descoberta na verificação; registro do gap para o repo do opencode: `~/Code/propositions/opencode/prefill-prompt-sem-submit.md` — se o repo ganhar a flag, `plan` passa a usar pre-fill)_
- **Ao sair do opencode, o terminal volta ou morre?** **Opções:** A) retorna ao shell no worktree (sem `exec`) | B) `exec opencode` (substitui o shell). **Recomendação:** A — volta para um terminal utilizável no worktree; `exec` é o escape para quem quiser. _(confirmado no gate — e sem auto-kill ao sair)_
## Referências
- GitHub Issue #571
- `scripts/worktree.mjs:329/400` — `if (go) console.log(\`cd ${dir}\`)`
- `.agents/shell/worktree.sh:42-53` — aplicação do cd pelo shell
- `.opencode/commands/worktree.md` — superfície que NÃO deve lançar o TUI
- Verificação: `opencode --help` (flags `--model`/`--auto`/`--prompt`); fonte do TUI (`packages/tui/src/home.tsx` auto-submete `--prompt`; `packages/tui/src/component/prompt/index.tsx` expande mensagem com `/` via `session.command`)

View file

@ -0,0 +1,71 @@
# Worktree CLI: `--go` vira o padrão (escape `--stay`) e `kill` volta ao main
Status: rascunho
Atualizado em: 2026-08-10
Issue: #569
Priority: P2
Model: composer-2.5
model-local: deepseek-v4-flash-high
Impeccable: A — N/A (CLI de dev; sem superfície de usuário de produto)
Canvas UI: N/A — sem UI
Appetite: ~0,5 dia eng; um outcome verificável (o terminal sempre termina no lugar certo)
## Intenção
Hoje `pnpm worktree next` / `plan` só aplicam o `cd` com `--go` explícito — mas **quase toda** invocação quer ir para o worktree; o raro é ficar. O usuário lança `worktree next --go` e `worktree plan --go` todo dia, e o caso incomum (automação, olhar sem entrar, rodar de dentro do opencode) é o que deveria pedir o flag. Além disso, `worktree kill` destrói o worktree em que o shell está e deixa o terminal órfão num diretório que não existe mais — o output até imprime "Volte ao main: cd …", mas ninguém aplica esse cd, então o prompt do shell fica num cwd morto até o usuário sair manualmente.
## Persona e fluxo
- **Persona / contexto:** Francisco no terminal (bash), fluxo diário de abrir/fechar worktrees; e o agente opencode rodando o comando `/worktree`.
- **Job principal:** um comando `worktree` que termina me deixando no lugar certo — dentro do worktree quando crio, no repo principal quando destruo.
- **Fluxo desejado:** `pnpm worktree next` (sem flags) cria/reusa e provisiona o worktree **e** aplica `cd <dir>` no shell; `pnpm worktree plan` idem; `pnpm worktree kill` destrói, remove os bancos **e** aplica `cd <main>` (`~/Code/teqo`); quem não quer entrar usa `--stay`.
- **Anti-goals de produto:** não criar um sistema de flags complexo (um escape só); não mudar a lógica determinística de branch/slot/provisionamento; não alterar o que `kill` destrói.
## Objetivo e aceite
- `pnpm worktree next` e `pnpm worktree plan` sem flags aplicam o `cd` no shell do terminal (hoje exigem `--go`).
- `--stay` suprime o `cd` (e a futura abertura de opencode — ver OPS26): o script imprime o caminho sem aplicar.
- `--go` explícito continua aceito como no-op — não quebra hábito, script de automação ou a doc existente.
- `pnpm worktree kill` termina com o shell no main repo; o cwd nunca fica num diretório destruído.
- O comportamento vale nas duas superfícies que aplicam o cd: função `worktree()` do `.agents/shell/worktree.sh` (terminal) e comando `/worktree` do opencode (`.opencode/commands/worktree.md`).
- **O comando `/worktree` no TUI do opencode continua criando/reutilizando o worktree (roda o script completo, com provisionamento) — o cd é consequência, não a função dele.** Com default-go, `/worktree next` cria + provisiona + aplica o cd na sessão; `/worktree plan` idem; `/worktree kill` destrói + aplica `cd <main>`.
- `AGENTS.md` (seção "Per-worktree environments") reflete a nova semântica default-go/`--stay`.
## Dados (intenção)
- **Vou apresentar dados?** Não — sem superfície de dados; é ergonomia de CLI de dev.
## Direção no codebase (hipótese)
- **Áreas prováveis:** `scripts/worktree.mjs` (cmdNext/cmdPlan imprimem `cd <dir>` por default; flag `--stay` no parseArgs; cmdKill imprime `cd <mainRoot>` no mesmo formato máquina que `next`/`plan` já usam); `.agents/shell/worktree.sh` (aplica o cd por default, suprime com `--stay`, aplica também no `kill`); `.opencode/commands/worktree.md` (texto de uso das três formas).
- **Precedente a olhar:** o formato `cd <dir>` já é o contrato entre o script e a função shell (sed parse na última linha); o kill já resolve `mainRoot` como `entries[0]?.path`.
- **Risco de acoplamento:** o opencode command (`/worktree`) e a função shell dividem a mesma saída do script — qualquer mudança de formato quebra os dois; manter UMA linha `cd …` no fim, sempre.
## Dependências
- Nenhuma. (Base de semântica para OPS26 e OPS27.)
## Fora de escopo
- Abertura do opencode ao "go" — item próprio (OPS26).
- O subcomando `worktree new` — item próprio (OPS27).
- Mudanças no provisionamento (porta/bancos/env) — pré-existente, não é o alvo.
## Rabbit holes de produto
- **"Vários escapes":** `--no-go`, `--here`, `--cd`… um só, com nome claro.
- **"O script deve detectar terminal vs opencode":** não — o script imprime o `cd`; quem aplica (shell function vs opencode command) decide o que fazer com ele. Manter o contrato de saída simples.
## Questões em aberto (produto)
- **Nome do escape?** **Opções:** A) `--stay` | B) `--no-go` | C) `--here`. **Recomendação:** A — curto, lê como o oposto de "go" e não parece flag de modo. _(confirmado no gate — `--stay`)_
- **`kill` deve suportar `--stay` (não voltar ao main)?** **Opções:** A) não — kill sempre volta ao main | B) sim, por simetria. **Recomendação:** A — ficar num cwd destruído é exatamente o bug que estamos corrigindo; quem roda kill por automação não depende do cwd do terminal pai.
## Referências
- GitHub Issue #569
- `scripts/worktree.mjs:444-481` — `cmdKill` já imprime "Volte ao main: cd ${mainRoot}"; nada aplica
- `scripts/worktree.mjs:329` e `400` — `if (go) console.log(\`cd ${dir}\`)`em`next`/`plan`
- `.agents/shell/worktree.sh:36-39` — cd só quando `--go` presente
- `.opencode/commands/worktree.md` — instrui o agente a aplicar o `cd` quando `--go`
- `AGENTS.md` seção "Per-worktree environments" — documenta `worktree next [--go]` etc.

View file

@ -0,0 +1,69 @@
# Worktree `new`: worktree genérico sem função pré-definida
Status: rascunho
Atualizado em: 2026-08-10
Issue: #572
Priority: P3
Model: composer-2.5
model-local: deepseek-v4-flash-high
Impeccable: A — N/A (CLI de dev; sem UI de produto)
Canvas UI: N/A — sem UI
Appetite: ~0,5–1 dia eng; um outcome verificável (worktree neutro criado e provisionado com um comando)
## Intenção
`worktree next` está amarrado à fila de claim (próxima Issue claimável) e `worktree plan` ao `/plan-issue` — os dois carregam uma função pré-definida. Mas às vezes a intenção é aberta: explorar uma ideia antes de virar Issue, planejar e executar algo sem registrar nada, ou só conversar com o agente num ambiente isolado (como esta sessão). Hoje não existe um subcomando para isso — o usuário precisaria de um `git worktree add` manual, sem provisionamento (porta, bancos próprios, envs). Queremos `worktree new [bag]`: um worktree **neutro**, com o mesmo ambiente isolado dos outros, sem propósito declarado.
## Persona e fluxo
- **Persona / contexto:** Francisco no terminal, querendo um espaço de trabalho isolado sem compromisso com a fila nem com a skill de planejamento.
- **Job principal:** criar um worktree provisionado e entrar nele, sem decidir antes o que vai fazer.
- **Fluxo desejado:** `worktree new` → branch `work/<n>` sequencial livre, provisionado (slot/porta/bancos próprios, comentário `gerado por pnpm worktree new`), e com o default-go (OPS24) termina com `cd` no worktree; com a OPS26, abre o opencode com os presets **sem** skill inicial — "apenas conversar". `worktree new <bag>` → branch `work/<bag>` (sufixo `-2`/`-3` em colisão). `--stay` suprime cd/launch.
- **Anti-goals de produto:** não virar um segundo `plan` (sem função de planejamento embutida); não colidir com a fila nem com os branches de claim; não propor branch sem provisionamento.
## Objetivo e aceite
- `worktree new [bag]` cria um worktree a partir de `origin/main` com branch `work/<bag>` (colisão → sufixo `-2`/`-3`) ou `work/<n>` sequencial livre sem bag — prefixo minúsculo `work/…` que **nunca** colide com `<Code>-<slug>` de `next` nem com `plans/plan-issue-…` de `plan`.
- Provisionamento idêntico ao `plan`: env isolado com `purpose: 'new'`, porta `3100+slot`, bancos próprios, migrations aplicadas; `--no-migrate` respeitado.
- Cada invocação cria um worktree **diferente** (mesmo comportamento de paralelismo do `plan`).
- Herda a semântica da OPS24 (`--go` default, `--stay`) e, quando a OPS26 estiver em main, o launch do opencode sem primeira mensagem.
- `worktree kill` funciona de dentro dele (já é o padrão dos outros — nada novo aqui além do teste de colisão de nomes).
- Help/uso do script (`pnpm worktree` sem args) documenta o subcomando; `AGENTS.md` atualizado.
## Dados (intenção)
- **Vou apresentar dados?** Não.
## Direção no codebase (hipótese)
- **Áreas prováveis:** `scripts/worktree.mjs` (novo `cmdNew` análogo ao `cmdPlan` — mesmo `planBranchName`-like para o namespace `work/`, mesmo fluxo de taken-set, `purpose: 'new'` no provision); `scripts/lib/worktree.mjs` (função de nome de branch genérica, se valer a pena generalizar); `.agents/shell/worktree.sh` + `.opencode/commands/worktree.md` + `AGENTS.md` (documentação).
- **Precedente a olhar:** `cmdPlan` (`scripts/worktree.mjs:343-401`) é o molde — branch sem Issue, `code: null`, taken-set de refs locais+remotos.
- **Risco de acoplamento:** o namespace `work/…` precisa continuar minúsculo (a regra de colisão de `next` é o prefixo maiúsculo `<Code>-<slug>`); o `readLiveSlots`/`worktreeEnvironment` já tratam qualquer branch.
## Dependências
- OPS24 (semântica default-go/`--stay` — o `new` nasce já no novo padrão, sem `--go` explícito).
- OPS26 (opcional: launch do opencode sem skill inicial — o `new` funciona sem ela).
## Fora de escopo
- Uma "terceira função" embutida (ex.: `worktree new --issue`) — para isso existem `next` e `plan`.
- Nomeação automática por data/hash randômico — sequencial (`<n>`) e por `bag` cobrem os dois usos.
- Mudanças no provisionamento.
## Rabbit holes de produto
- **"Worktree sem nome = bag aleatório":** nomes legíveis (bag) ou sequenciais bastam; aleatório só atrapalha o `kill`/localização.
- **"`new` deveria perguntar o que vamos fazer":** o ponto é justamente não perguntar — worktree neutro, a conversa decide depois.
## Questões em aberto (produto)
- **Prefixo do branch?** **Opções:** A) `work/<slug>` | B) `wip/<slug>` | C) `sandbox/<slug>`. **Recomendação:** A — neutro, não dá a entender "em andamento" nem "brinquedo". _(confirmado no gate — `work/`)_
- **`new` abre o opencode (OPS26) com o quê?** **Opções:** A) com os presets mas **sem** primeira mensagem (só modelo + auto-approve; "apenas conversar") | B) sem abrir (só cd). **Recomendação:** A — é o caso de uso explícito do pedido ("apenas conversar com o agente"); quem não quer usa `--stay`. _(confirmado no gate)_
## Referências
- GitHub Issue #572
- `scripts/worktree.mjs:343-401` — `cmdPlan`: molde de branch sem Issue (taken-set, `code: null`, provision)
- `scripts/lib/worktree.mjs` — `planBranchName` (padrão de nome com sufixo de colisão a generalizar para `work/`)
- `AGENTS.md` seção "Per-worktree environments" — onde documentar o subcomando