$TMPDIR/chatcli-agent-<random>/ e exposto ao agente via a variável de ambiente CHATCLI_AGENT_TMPDIR. Esse diretório resolve duas dores recorrentes:
- O agente precisa criar um script temporário (por exemplo, um
.shpara um patch complexo) mas o boundary do/coderbloqueia escritas fora do projeto, forçando-o a poluir a árvore do repositório. - Quando um tool result é truncado e o ChatCLI salva o conteúdo completo em disco com a marca
[full output saved to /tmp/...], o agente não consegue ler esse arquivo porque o caminho está fora do workspace boundary.
Estrutura
<random> vem de os.MkdirTemp — único por processo. Isso evita colisão entre múltiplos chatcli rodando em paralelo no mesmo host.
Como o agente sabe que existe?
O system prompt do/agent e do /coder recebe automaticamente um bloco com:
- Caminho literal do scratch dir resolvido na hora (o agente não precisa expandir variável).
- Instrução para usar
$CHATCLI_AGENT_TMPDIRem comandos shell quando preferir. - Padrão de uso para os marcadores de truncamento: quando ler
[full output saved to /tmp/chatcli-agent-XXX/tool-results/...], abrir o arquivo comread_fileem vez de refazer a tool call original.
Cenário 1 — Criar e executar script temporário
No/coder, o modelo tem duas vias para staging de script:
Via direta com path absoluto
validatePath do engine reconhece o aux path registrado pela InitSessionWorkspace e libera a escrita.
Via shell expansion no exec
$CHATCLI_AGENT_TMPDIR é o shell filho, que herda a variável do processo do ChatCLI.
Cenário 2 — Recuperar miolo de output truncado
O sistema de orçamento de resultados trunca tool results grandes (> 20K chars por padrão) e salva o conteúdo completo emtool-results/. O preview retornado ao modelo contém um marcador como:
tool-results/ estão na read allowlist do agente, então o modelo simplesmente abre o arquivo:
Lifecycle
| Evento | Ação |
|---|---|
NewChatCLI (startup) | agent.InitSessionWorkspace(logger) cria os dirs, exporta CHATCLI_AGENT_TMPDIR, registra os paths nos validators |
| Cada turno do agente | Aux paths consultados pelo validatePath (engine) e IsReadAllowed (read validator) |
| Tool result excede orçamento | tool-results/ recebe o conteúdo completo; preview com marcador volta para o modelo |
ChatCLI.cleanup() (exit, Ctrl+D, SIGTERM) | ws.Cleanup() faz os.RemoveAll do dir raiz; env var é desexportada |
Configuração
| Variável | Descrição | Default |
|---|---|---|
CHATCLI_AGENT_TMPDIR | Apenas leitura. Caminho absoluto do scratch dir, exportado automaticamente para subprocessos | (definido na inicialização) |
CHATCLI_AGENT_KEEP_TMPDIR | Se true, pula o cleanup e mantém os arquivos após o exit (para depuração) | false |
Segurança
O workspace de sessão não afrouxa o boundary do agente para o resto do sistema:- O scratch dir vive em
os.TempDir()($TMPDIRno macOS,/tmpno Linux), com permissão0700no diretório raiz da sessão. - Apenas esse diretório específico (criado por
os.MkdirTemp) é adicionado à allowlist — não o/tmpinteiro. - Os validators (
engine.validatePath,SensitiveReadPaths.IsReadAllowed) seguem aplicando o resto das proteções: bloqueio de paths sensíveis (/etc/shadow,~/.ssh,~/.aws/,~/.gnupg, etc.) e o boundary do projeto. - O webfetch com
save_to_file=trueconfina escritas ao scratch dir viafilepath.Base+ verificação pós-resolve, mesmo se o modelo tentar passar um caminho absoluto.
Próximos Passos
Resultados de Tools
Como o orçamento decide o que truncar e onde persistir.
Subagent Delegation
Delegar tarefas pesadas para um subagente com contexto isolado.
Web Tools
save_to_file do @webfetch usa o scratch dir.Variáveis de Ambiente
Lista completa das variáveis que controlam o workspace.