8.6 KiB
OPS119 — worktree plan: abrir sem auto-enviar o /plan-issue (mensagem opcional na linha)
Status: rascunho Atualizado em: 2026-09-15 Issue: #1066 Priority: P2 Impeccable: A — N/A (CLI/shell, sem superfície de produto) Rascunho UI: N/A — sem UI Appetite: ~0,5 dia eng; mudança de comportamento do launch + testes + textos Responsável: —
Intenção
Desde a OPS110 o launch do terminal delega ao scripts/agent-session.mjs e o driver destacado auto-submete /plan-issue na sessão compartilhada. Isso veio do OPS31 (Issue #593), que escolheu auto-envio por simetria com o next. Na prática o planejamento quase sempre quer contexto na primeira mensagem — e hoje ele não cabe: abrir já enviado engole a chance de escrever o pedido. Queremos que worktree plan (sem argumento) abra a sessão sem mensagem (o humano digita /plan-issue), e que worktree plan "<mensagem>" continue abrindo já enviado com /plan-issue <mensagem> — o texto vira também o rótulo do bag/branch, espelhando o fix. Isto reverte parte do OPS31 de propósito, com evidência de uso.
Persona e fluxo
- Persona / contexto: o humano (dono do repo) no terminal, abrindo um worktree para planejar em
/plan-issue, com o contexto da ideia na cabeça. - Job principal: abrir o worktree de planejamento e conseguir descrever o que quer antes de a skill rodar.
- Fluxo desejado:
worktree plan→ cria o worktree, provisiona o ambiente,cde abre a sessão sem nenhuma mensagem enviada; o humano digita/plan-issuecom o contexto que quiser.worktree plan "revisa o gate do designer"→ mesma abertura, mas o driver auto-submete/plan-issue revisa o gate do designer; o texto também batiza o branch (plans/plan-issue-revisa-o-gate-do-designer).
- Anti-goals de produto: não virar mecanismo de prefill-draft do opencode; não mudar
next/new/fix,--staynem o comando/worktree.
Objetivo e aceite
worktree plansem argumento abre a sessão persistente sem driver (nenhuma mensagem auto-submetida) — mesmo contrato observável donew.worktree plan "<mensagem>"auto-submete/plan-issue <mensagem>(uma única mensagem) e usa a mesma mensagem como bag do branch — simétrico aofix <bag>.nextcontinua com/work-issue --issue <N>;newcontinua driverless;fix <bag>continua com/bug-fix <bag>;--staye o comando/worktreedo opencode ficam intactos.- A mensagem passa pela mesma sanitização do
fixe um bag vazio não gera driver.
Dados (intenção)
- Vou apresentar dados? Não — mudança de comportamento de CLI/shell, sem superfície de dados.
- Decisões desbloqueadas: o humano decide o texto de abertura do planejamento; o executor confere bag, branch e prompt num só lugar (como no
fix). - Forma: adiada ao plano de implementação.
Dados da decisão (literais)
SESSION_COMMAND_BY_PURPOSE(scripts/lib/agent-session.mjs:169-174):plan: 'plan-issue'permanece como nome da skill; o que muda é quando a invocação existe (abaixo).purposeInvocation(scripts/lib/agent-session.mjs:184-199): ganha o ramo doplan— sem argumento →null(sessão sem driver, comonew); com argumento →{ command: 'plan-issue', arguments: <sanitized> }, com a mesma sanitização dofix(:195,replace(/["\\]/g, '')+trim).opencodeLaunchDirective(scripts/lib/worktree.mjs:202-232): a emissão de--argument="<bag>"deixa de ser só dofix(:227-230) e passa a valer parafixeplan(condiçãopurpose === 'fix' || purpose === 'plan').cmdPlan(scripts/worktree.mjs:755-764): passaargument: bagaocmdNamespaceBranch, como ocmdFixjá faz (:810). O runner (:675-743, print em:740) e odriverArgs(:287-313, apêndice só seargumentsfor truthy,:311) não mudam.- Posicional intacto:
plansegue lendo sópositional[1](scripts/worktree.mjs:1038) e o bag continua virando slug viaplanBranchName(scripts/lib/worktree.mjs:277-278) — agora acumulando a função de mensagem, como ofix. - Testes a repin:
tests/unit/agentSession.unit.spec.ts:218-224(plan sem msg →null; plan com msg →{ command:'plan-issue', arguments:'<msg>' });tests/unit/worktree.unit.spec.ts:190-209(diretiva do plan sem arg inalterada) e:255-266(hoje "argument é só do fix" → passa a:plancarrega--argument,newsegue ignorando). - Textos a atualizar: uso do
planemscripts/worktree.mjs:980-992,.agents/shell/worktree.sh:9-31,43-49,102-118,.agents/skills/worktree-next-issue/SKILL.md:23,30,34, parágrafo de worktrees doAGENTS.mde uma entrada emdocs/changelog/. - Supersede:
docs/plans/worktree-plan-abre-opencode-com-plan-issue.md(OPS31/#593) — auto-envio deixa de ser o default sem argumento; re-flagar~/Code/propositions/opencode/prefill-prompt-sem-submit.md.
Direção no codebase (hipótese)
- Áreas prováveis:
scripts/lib/agent-session.mjs(mapa +purposeInvocation),scripts/lib/worktree.mjs(diretiva +cmdPlan) e os textos emscripts/worktree.mjs/.agents/shell/worktree.sh/.agents/skills/worktree-next-issue/SKILL.md. - Precedente a olhar: o
fix— o caminho bag→--argument→driver já existe e é o espelho exato do que oplanpassa a fazer; OPS110 (delegação das sessões). - Risco de acoplamento: abrir sem mensagem é a mesma sessão endereçável da OPS110, apenas sem
driverPid; não tocar emkill/attach(encerram a sessão driverless normalmente).
Dependências
- Nenhuma dura. O opencode instalado (1.18.31) não tem prefill-sem-submit (
--promptauto-envia; não há flag de draft), por isso o fallback "abrir sem mensagem"; a proposição upstream é dependência futura, não bloqueio.
Fora de escopo
- Implementar prefill-sem-submit no opencode (upstream; anotar na proposição).
- Mudar
next/new/fix,--staye o comando/worktreedo opencode. - Qualquer mudança em claim, banco ou provisionamento.
Rabbit holes de produto
- "Já que estamos mexendo, deixa o plan com subcomandos/prompt rico." Explosão de sintaxe de CLI. Corte neste item: só o par sem-arg/arg, espelhando o
fix. - "Abre com prefill e espera o upstream." Bloqueia a entrega por uma feature que o opencode não tem. Corte: fallback driverless agora; prefill re-flagado.
Questões em aberto (produto)
- O fallback "abrir sem mensagem" basta, ou vale perseguir prefill-sem-submit no upstream? Opções: A) entregar o fallback agora e re-flagar a proposição; B) bloquear este item até o opencode ganhar prefill. Recomendação: A — a fricção real (digitar) é baixa e o auto-envio continua via
worktree plan "<msg>"; prefill fica como dependência upstream futura. (assumido — validar no gate) - O bag continua sendo rótulo de branch e, agora, também mensagem? Opções: A) sim, idêntico ao
fix(um texto faz as duas coisas); B) separar bag de mensagem (nova flag). Recomendação: A — preserva a sintaxe[bag]e o precedente dofix; separar criaria um segundo vocabulário. (assumido — validar no gate)
Fases (ordem de entrega)
- F1 — Sessão (owner):
SESSION_COMMAND_BY_PURPOSE/purposeInvocationpara o par doplan(sem msg →null; com msg →/plan-issue <msg>). - F2 — Launch:
opencodeLaunchDirectiveemite--argumentparaplan;cmdPlanpassa o bag. - F3 — Testes + textos: repin dos dois specs, atualização da doc de uso e entrada de changelog.
Verificação
- Unit verde nos dois specs repinados; walkthrough manual:
worktree planabre sem mensagem eworktree plan "mensagem"abre com/plan-issue mensageme branchplans/plan-issue-mensagem. - Não-regressão: comparar as linhas de diretiva de
next/new/fixcom as de hoje.
Riscos
- Divergência entre bag (slug) e mensagem (texto sanitizado). Mitigação: reusar a sanitização do
fixna diretiva e oslugifyexistente no branch. - Regressão no
new/fixao mexer na condição da diretiva. Mitigação: teste travandonewignorar argumento efixmanter o comportamento. - Texto/doc dizendo "plan auto-submete
/plan-issue". Mitigação: varredura por/plan-issuenos textos listados antes do commit.
Referências
- GitHub Issue #1066
- Rascunho UI (gate): N/A
scripts/lib/agent-session.mjs·scripts/lib/worktree.mjs·scripts/worktree.mjs— código a editar primeirodocs/plans/worktree-plan-abre-opencode-com-plan-issue.md(OPS31/#593 — decisão superada)~/Code/propositions/opencode/prefill-prompt-sem-submit.md(re-flagar)AGENTS.md— parágrafo de worktrees / sessões persistentes