pantheon-opencode 1.5.2 → 1.6.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pantheon/code-mode/README.md +4 -2
- package/.pantheon/code-mode/checkpoint_session.py +138 -102
- package/.pantheon/code-mode/compress-inline.py +102 -57
- package/.pantheon/code-mode/manifest.json +2 -8
- package/AGENTS.global.md +182 -0
- package/AGENTS.md +10 -891
- package/CHANGELOG.md +343 -0
- package/README.md +577 -79
- package/README.pt-BR.md +345 -60
- package/bin/pantheon-init.mjs +26 -3
- package/commands/pantheon-audit.md +7 -1
- package/commands/pantheon-consolidate.md +1 -1
- package/commands/pantheon-deepwork.md +14 -3
- package/commands/pantheon-focus.md +17 -0
- package/commands/pantheon-optimize.md +2 -2
- package/commands/pantheon-vision.md +61 -12
- package/package.json +30 -11
- package/plugin.json +2 -2
- package/pyproject.toml +11 -16
- package/scripts/build-agents-md.mjs +376 -58
- package/scripts/changelog-merge.mjs +161 -0
- package/scripts/check-plugin-v2-coverage.mjs +213 -0
- package/scripts/ci-validate-yaml.py +7 -5
- package/scripts/{code_mode_server.py → code_mode.py} +119 -27
- package/scripts/cost.mjs +244 -41
- package/scripts/doctor.mjs +236 -29
- package/scripts/install/agents-md.mjs +4 -4
- package/scripts/install/cli-ui.mjs +1 -1
- package/scripts/install/config-migration.mjs +319 -6
- package/scripts/install/health-check.mjs +26 -37
- package/scripts/install/interactive.mjs +7 -7
- package/scripts/install/migrate.mjs +1 -1
- package/scripts/install/opencode-version.mjs +246 -4
- package/scripts/install/opencode.mjs +627 -179
- package/scripts/install/plugin.mjs +43 -9
- package/scripts/install/shared.mjs +120 -12
- package/scripts/install/vision-prompt.mjs +161 -0
- package/scripts/install-mcp.mjs +28 -9
- package/scripts/{mcp_persistence_server.py → mcp_persistence.py} +392 -78
- package/{src/mcp/mcp_resources_server.py → scripts/mcp_resources.py} +2 -2
- package/scripts/{memory_mcp_server.py → memory_mcp.py} +372 -198
- package/scripts/postinstall.mjs +0 -7
- package/scripts/probe-context-rehydrate.mjs +36 -13
- package/scripts/probe-pantheon-cost.mjs +71 -15
- package/scripts/prune.mjs +2 -2
- package/scripts/run-node-tests.mjs +189 -0
- package/scripts/sync-artifacts.mjs +26 -13
- package/scripts/sync-tui.mjs +24 -3
- package/scripts/test-opencode-v2-sandbox.sh +1913 -0
- package/scripts/validate-routing.mjs +43 -3
- package/scripts/validate-sandbox-install.mjs +138 -0
- package/scripts/versioning.mjs +13 -1
- package/scripts/vision-status.mjs +682 -0
- package/skills-lock.json +15 -16
- package/src/agents/aphrodite.md +20 -37
- package/src/agents/apollo.md +7 -3
- package/src/agents/athena.md +63 -35
- package/src/agents/demeter.md +8 -28
- package/src/agents/gaia.md +1 -1
- package/src/agents/hephaestus.md +10 -21
- package/src/agents/hermes.md +15 -38
- package/src/agents/iris.md +1 -1
- package/src/agents/mnemosyne.md +23 -60
- package/src/agents/nyx.md +1 -1
- package/src/agents/prometheus.md +16 -20
- package/src/agents/talos.md +10 -2
- package/src/agents/themis.md +5 -5
- package/src/agents/zeus.md +99 -130
- package/src/instructions/agent-return-format.instructions.md +18 -3
- package/src/instructions/backend-standards.instructions.md +2 -0
- package/src/instructions/frontend-standards.instructions.md +3 -1
- package/src/instructions/memory-protocol.instructions.md +11 -110
- package/src/instructions/zeus-anti-stall.instructions.md +14 -61
- package/src/instructions/zeus-communication-rules.instructions.md +0 -1
- package/src/instructions/zeus-council-synthesis.instructions.md +32 -260
- package/src/instructions/zeus-memory-operations.instructions.md +26 -0
- package/src/instructions/zeus-timeout-retry.instructions.md +40 -87
- package/src/mcp/{code_mode_server.py → code_mode.py} +119 -27
- package/src/mcp/eval_store.py +2 -2
- package/src/mcp/mcp_codemap_module.py +559 -129
- package/src/mcp/{mcp_persistence_server.py → mcp_persistence.py} +392 -78
- package/{scripts/mcp_resources_server.py → src/mcp/mcp_resources.py} +2 -2
- package/src/mcp/{memory_mcp_server.py → memory_mcp.py} +373 -250
- package/src/mcp/{pantheon_vision_server.py → pantheon_vision.py} +396 -40
- package/src/mcp/requirements-mcp.txt +10 -6
- package/src/mcp/requirements-vision.txt +4 -2
- package/src/pantheon/cost-command.ts +399 -101
- package/src/pantheon/delegation-enforce.ts +10 -1
- package/src/pantheon/model-command.ts +18 -7
- package/src/pantheon/presets.d.mts +0 -8
- package/src/pantheon/presets.mjs +5 -32
- package/src/pantheon/todo-enforcer.ts +1 -1
- package/src/pantheon/v2-bounded-read.ts +640 -0
- package/src/pantheon/v2-delegation-enforce.ts +214 -0
- package/src/pantheon/v2-execute-after.ts +186 -0
- package/src/pantheon/v2-tools.ts +429 -0
- package/src/pantheon/v2-unsupported.d.mts +11 -0
- package/src/pantheon/v2-unsupported.mjs +90 -0
- package/src/pantheon/v2-vision.ts +622 -0
- package/src/pantheon/vision-local.ts +531 -0
- package/src/pantheon/vision.ts +1161 -116
- package/src/plugin-v2.ts +1244 -288
- package/src/plugin.ts +12 -9
- package/src/plugins/tui/dist/server.d.ts +1 -2
- package/src/plugins/tui/dist/server.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui-v2.d.ts +154 -0
- package/src/plugins/tui/dist/tui-v2.d.ts.map +1 -0
- package/src/plugins/tui/dist/tui-v2.js +659 -0
- package/src/plugins/tui/dist/tui-v2.js.map +1 -0
- package/src/plugins/tui/dist/tui.d.ts +85 -82
- package/src/plugins/tui/dist/tui.d.ts.map +1 -1
- package/src/plugins/tui/dist/tui.js +72 -59
- package/src/plugins/tui/index-v2.ts +6 -0
- package/src/plugins/tui/package-lock.json +5504 -1341
- package/src/plugins/tui/package.json +25 -15
- package/src/plugins/tui/src/index-v2.tsx +734 -0
- package/src/plugins/tui/src/index.tsx +106 -85
- package/src/plugins/tui/src/opencode-v2.d.ts +13 -0
- package/src/plugins/tui/tsconfig.build.json +5 -0
- package/src/plugins/tui/tsconfig.typecheck.json +5 -0
- package/src/plugins/tui/tsdown.config.ts +22 -2
- package/src/plugins/tui/tui-v2.ts +2 -0
- package/src/plugins/tui/tui.ts +3 -0
- package/src/routing.yml +11 -22
- package/src/skills/README.md +34 -39
- package/src/skills/agent-coordination/SKILL.md +7 -2
- package/src/skills/artifact-management/SKILL.md +12 -5
- package/src/skills/auto-continue/SKILL.md +54 -95
- package/src/skills/code-review-checklist/SKILL.md +5 -5
- package/src/skills/context-compression/SKILL.md +26 -879
- package/src/skills/session-goal/SKILL.md +14 -5
- package/src/skills/spec-driven-development/SKILL.md +3 -1
- package/src/skills/tdd-with-agents/SKILL.md +18 -10
- package/.pantheon/code-mode/eval-llm-judge.py +0 -255
- package/.pantheon/code-mode/eval-monte-carlo.py +0 -368
- package/.pantheon/code-mode/eval-run.py +0 -197
- package/.pantheon/code-mode/eval-static.py +0 -321
- package/.pantheon/code-mode/session-end-save.py +0 -186
- package/.pantheon/code-mode/session-end-save.sh +0 -18
- package/opencode.json +0 -58
- package/scripts/recover-zenodo-deposition.mjs +0 -146
- package/scripts/test-opencode-v1-v2-sandbox.sh +0 -862
- package/scripts/validate-zenodo-release.mjs +0 -154
- package/scripts/zenodo-artifact.mjs +0 -94
- package/scripts/zenodo-release-state.mjs +0 -53
- package/src/skills/orchestration-workflow/SKILL.md +0 -311
package/README.pt-BR.md
CHANGED
|
@@ -10,7 +10,7 @@ e equipes que querem mais estrutura sem perder o controle do próprio código.
|
|
|
10
10
|
|
|
11
11
|
[](https://github.com/ils15/pantheon-opencode/releases/latest)
|
|
12
12
|
[](https://github.com/ils15/pantheon-opencode/actions)
|
|
13
|
-
[](https://doi.org/10.5281/zenodo.22650136)
|
|
14
14
|
|
|
15
15
|
## O que é?
|
|
16
16
|
|
|
@@ -31,7 +31,7 @@ de planejar o trabalho, avançar, conferir resultados e preservar o contexto
|
|
|
31
31
|
|
|
32
32
|
## Comece em 2 minutos
|
|
33
33
|
|
|
34
|
-
Requisitos: [OpenCode 1.18.4+](https://opencode.ai/docs/) e Node.js 22
|
|
34
|
+
Requisitos: [OpenCode 1.18.4+](https://opencode.ai/docs/) e Node.js `^22.22.2 || ^24.15.0 || >=26.0.0`.
|
|
35
35
|
|
|
36
36
|
No projeto em que você quer usar o Pantheon:
|
|
37
37
|
|
|
@@ -53,6 +53,10 @@ Com o OpenCode em execução, descreva o resultado que você quer:
|
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
O Pantheon ajuda a transformar esse pedido em um plano e em etapas revisadas.
|
|
56
|
+
Quando você pede um plano ou inicia `/pantheon-deepwork`, Athena devolve o plano
|
|
57
|
+
completo para Zeus, que o apresenta na conversa principal antes de pedir
|
|
58
|
+
aprovação. O pedido de aprovação não ficará separado de um plano escondido na
|
|
59
|
+
conversa de um subagente.
|
|
56
60
|
|
|
57
61
|
## Para quem é?
|
|
58
62
|
|
|
@@ -71,8 +75,8 @@ verificações repetíveis e passagens claras entre etapas do trabalho.
|
|
|
71
75
|
|
|
72
76
|
## Status
|
|
73
77
|
|
|
74
|
-
Versão operacional neste checkout: **v1.
|
|
75
|
-
não afirma publicação). O Pantheon foi feito para OpenCode e depende da
|
|
78
|
+
Versão operacional neste checkout: **v1.6.0-beta.1** (primeira beta compatível
|
|
79
|
+
com OpenCode 2; esta página não afirma publicação). O Pantheon foi feito para OpenCode e depende da
|
|
76
80
|
disponibilidade e da configuração do OpenCode e dos serviços opcionais que você
|
|
77
81
|
escolher. Veja as [releases](https://github.com/ils15/pantheon-opencode/releases)
|
|
78
82
|
e o [changelog](CHANGELOG.md) para acompanhar as mudanças publicadas.
|
|
@@ -103,25 +107,17 @@ falha fechado, sem fallback silencioso. O `doctor` valida o manifest e o
|
|
|
103
107
|
SHA-256 de cada script sem regenerá-lo.
|
|
104
108
|
|
|
105
109
|
|
|
106
|
-
## Novidades da 1.
|
|
110
|
+
## Novidades da 1.6.0-beta.1
|
|
107
111
|
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
symlink/traversal nos caminhos de recursos.
|
|
114
|
-
- Compatibilidade com OpenCode V2: merge de configuração `plugins` /
|
|
115
|
-
`mcp.servers.enabled` e launch stdio MCP com PWD correto.
|
|
116
|
-
- `doctor` e health checks de instalação expandidos.
|
|
117
|
-
- Validador de sandbox para instalações globais
|
|
118
|
-
(`scripts/test-opencode-v1-v2-sandbox.sh`) cobrindo OpenCode V1/V2 lado a
|
|
119
|
-
lado — veja [Validação em sandbox](#validação-em-sandbox-v1v2).
|
|
120
|
-
- A flag `--prompts` do instalador está planejada para uma release futura.
|
|
112
|
+
- Primeira beta compatível com o contrato de plugin do OpenCode 2.
|
|
113
|
+
- Remoção do pipeline legado de vector-memory, preservando a busca por palavras-
|
|
114
|
+
chave SQLite FTS5/BM25 e as ferramentas de codemap `code_*`.
|
|
115
|
+
- Validações de CI e release fail-closed; `doctor` e o sandbox exclusivo V2
|
|
116
|
+
cobrem o caminho de instalação do OpenCode 2.
|
|
121
117
|
|
|
122
|
-
## OpenCode V1/V2 — Versão dupla (1.
|
|
118
|
+
## OpenCode V1/V2 — Versão dupla (1.6.0-beta.1)
|
|
123
119
|
|
|
124
|
-
O Pantheon tem dois contratos de plugin OpenCode **exclusivos**. A configuração
|
|
120
|
+
Esta é a primeira beta compatível com o OpenCode 2. O Pantheon tem dois contratos de plugin OpenCode **exclusivos**. A configuração
|
|
125
121
|
comum do OpenCode pode ser compartilhada, mas o registro do plugin Pantheon é
|
|
126
122
|
selecionado por instalação; os plugins Pantheon V1 e V2 nunca devem ser
|
|
127
123
|
registrados juntos.
|
|
@@ -130,15 +126,137 @@ registrados juntos.
|
|
|
130
126
|
|---|---|---|
|
|
131
127
|
| Chave de config do OpenCode | `plugin` singular | `plugins` plural |
|
|
132
128
|
| Registro Pantheon | `src/plugin.ts` mais `src/plugins/pantheon-hooks.ts` | `pantheon-opencode/plugin-v2` (`src/plugin-v2.ts`) |
|
|
133
|
-
| Contrato de runtime | Plugin Pantheon V1: 6 ferramentas (`hashline_edit`, as 3 ferramentas de goal, `pantheon_cost`, `pantheon_model`), hooks de evento/ferramenta e tratamento de compactação V1 | Plugin V2 completo:
|
|
129
|
+
| Contrato de runtime | Plugin Pantheon V1: 6 ferramentas (`hashline_edit`, as 3 ferramentas de goal, `pantheon_cost`, `pantheon_model`), hooks de evento/ferramenta e tratamento de compactação V1 | Plugin V2 completo: 3 ferramentas de orquestração mais `vision_describe` quando o catálogo de modelos está disponível, 5 assinaturas de eventos, session hooks (`prompt`, `context`), um hook `execute.before` que impõe sessões somente-leitura, além de transforms de configuração |
|
|
134
130
|
| APIs V1 | Registradas | Definições próprias de ferramentas via `ctx.tool.transform()` — não pelo caminho do plugin V1 |
|
|
135
131
|
|
|
136
|
-
O plugin V2 fornece
|
|
137
|
-
`pantheon_goal_create`, `pantheon_goal_get`, `pantheon_goal_update`,
|
|
132
|
+
O plugin V2 fornece 3 ferramentas de orquestração (`hashline_edit`,
|
|
138
133
|
`pantheon_cost`, `pantheon_model`), 4 assinaturas de eventos (`session.created`,
|
|
139
134
|
`session.idle`, `session.error`, `session.compacted`), session hooks (`prompt`,
|
|
140
|
-
`context`) e
|
|
141
|
-
|
|
135
|
+
`context`) e um hook de ferramenta `execute.before` que impõe sessões
|
|
136
|
+
somente-leitura. As 3 ferramentas de goal **não** são
|
|
137
|
+
registradas no V2: o goal loop precisa de um `GoalStore`, de um
|
|
138
|
+
`GoalLoopClient` e de um `BackgroundJobBoard`, nenhum dos quais o
|
|
139
|
+
`PluginContext` do V2 expõe, então a lacuna é reportada como o marcador de
|
|
140
|
+
recurso sem suporte `goal-tools`. Use o contrato V1 se precisar do goal loop.
|
|
141
|
+
|
|
142
|
+
O V2 também registra `vision_describe` quando `ctx.model.list()` está
|
|
143
|
+
disponível. A ferramenta verifica a entrada de imagem no catálogo atual,
|
|
144
|
+
prioriza o modelo pago `opencode-go/mimo-v2.6-flash` (modelos free-tier são
|
|
145
|
+
excluídos da seleção automática — o gateway direto os rejeita com HTTP 403, só
|
|
146
|
+
funcionam de dentro do OpenCode; um pin explícito em
|
|
147
|
+
`PANTHEON_VISION_MODEL`/config/preset continua sendo honrado, então seu 403 vira
|
|
148
|
+
um erro acionável em vez de uma troca silenciosa) e envia a imagem
|
|
149
|
+
diretamente ao endpoint autenticado do OpenCode Zen. A requisição carrega o
|
|
150
|
+
session id vivo no header Zen-only `x-opencode-session` exigido pelo gateway
|
|
151
|
+
(nunca enviado a um provider não-Zen, e nunca logado). As credenciais vêm de
|
|
152
|
+
`opencode auth login` ou `PANTHEON_OPENCODE_API_KEY`; sem modelo compatível ou
|
|
153
|
+
credenciais, a ferramenta retorna um erro explícito em vez de inventar uma
|
|
154
|
+
descrição. Esse caminho funciona sem a ponte V1 opcional.
|
|
155
|
+
O hook de prompt V2 também preserva as referências dos anexos e orienta Zeus a
|
|
156
|
+
inspecionar imagens relevantes e repassar a referência e observações concisas a
|
|
157
|
+
Aphrodite. Bytes inline não são copiados para o texto persistido do prompt, e a
|
|
158
|
+
imagem não autoriza apagar nem reverter alterações fora do escopo.
|
|
159
|
+
|
|
160
|
+
O caminho nativo do turno de chat escolhe o modelo de visão numa precedência
|
|
161
|
+
fixa: a variável `PANTHEON_VISION_MODEL`, depois `visionModel` em
|
|
162
|
+
`opencode-vision.json`, depois `vision.model` do preset ativo, depois descoberta
|
|
163
|
+
automática no catálogo de providers do host (`GET /config/providers`) e, por
|
|
164
|
+
fim, o padrão embutido. A descoberta é conservadora e somente paga: mantém
|
|
165
|
+
apenas entradas com imagem (`capabilities.input.image`) cujo provider é Zen
|
|
166
|
+
confiável ou cujo pacote `npm` é OpenAI-compatível (`@ai-sdk/openai-compatible` /
|
|
167
|
+
`@ai-sdk/openai`), EXCLUI entradas free-tier (`-free` ou `cost.input <= 0` — o
|
|
168
|
+
gateway direto as rejeita com HTTP 403), escolhe a entrada mais barata restante
|
|
169
|
+
e faz cache do catálogo por 60
|
|
170
|
+
segundos por processo; um modelo incompatível simplesmente cai no fallback da
|
|
171
|
+
tool MCP de visão. A base URL vem do `api.url` da entrada do catálogo, e os
|
|
172
|
+
endpoints Zen legados permanecem como fallback quando não há catálogo. As
|
|
173
|
+
credenciais seguem o endpoint: para um endpoint Zen, as variáveis compartilhadas
|
|
174
|
+
`PANTHEON_OPENCODE_API_KEY` / `OPENCODE_API_KEY` são tentadas primeiro e depois o
|
|
175
|
+
auth store do OpenCode (o provider resolvido primeiro, depois as entradas legadas
|
|
176
|
+
`opencode-go` / `opencode`); para um endpoint não-Zen, apenas a entrada do próprio
|
|
177
|
+
provider no auth store é usada — as variáveis compartilhadas e as entradas Zen
|
|
178
|
+
legadas nunca são anexadas a uma base URL não-Zen. Um modelo de visão
|
|
179
|
+
configurado explicitamente e qualificado sempre vence a descoberta — um pin que
|
|
180
|
+
não qualifica (não-Zen, text-only ou fora do catálogo) é descartado e a seleção
|
|
181
|
+
automática assume. O `pantheon-opencode init` oferece um
|
|
182
|
+
passo opcional de vision em sessões TTY interativas — a descoberta automática é
|
|
183
|
+
o default e não grava nada; pinar faz merge de `visionModel` no
|
|
184
|
+
`opencode-vision.json` global; fluxos não-interativos nunca perguntam nem gravam.
|
|
185
|
+
|
|
186
|
+
A pergunta do usuário é injetada no prompt de visão nos caminhos nativo e V2,
|
|
187
|
+
aparada e limitada a 2000 caracteres; a mesma imagem com uma pergunta diferente
|
|
188
|
+
gera nova descrição, enquanto uma repetição idêntica dentro do TTL de cache
|
|
189
|
+
reutiliza o texto guardado. O describe nativo é robusto por construção: o
|
|
190
|
+
timeout escala de uma base de 20 segundos a cerca de 10 segundos por MB de
|
|
191
|
+
payload até um teto de 300 segundos, e uma checagem de orientação EXIF sem
|
|
192
|
+
dependências (JPEG) adiciona uma dica textual para o vision model descrever a
|
|
193
|
+
imagem rotacionada ou espelhada na posição correta — só detecção, os pixels
|
|
194
|
+
nunca são reescritos, e a orientação entra na chave do cache.
|
|
195
|
+
|
|
196
|
+
A visão degrada numa cadeia explícita — nativa → tool MCP de visão → local.
|
|
197
|
+
Quando a nativa está indisponível e a tool MCP de visão não está presente, a
|
|
198
|
+
imagem é substituída por extração local determinística: dimensões, formato e
|
|
199
|
+
tamanho do header PNG/JPEG/GIF/WebP, cores dominantes para PNG RGB/RGBA e OCR
|
|
200
|
+
somente quando o binário `tesseract` está no `PATH`. Nunca fabrica conteúdo — a
|
|
201
|
+
degradação é declarada explicitamente. As tools `vision_describe` e `vision_ocr`
|
|
202
|
+
do MCP degradam para esse modo local quando não há credencial de gateway, sem
|
|
203
|
+
dependências novas. (A `vision_analyze` exige credencial de gateway e retorna um
|
|
204
|
+
erro explícito.) Trade-offs deliberados, registrados para não serem
|
|
205
|
+
revertidos por acidente: o Pantheon descreve cada imagem uma vez e mantém o
|
|
206
|
+
texto no histórico (council 2026-08-03) em vez de preservar a imagem original
|
|
207
|
+
para re-observação a cada turno; o describe-always prioriza latência zero em vez
|
|
208
|
+
de uma tool `describe_image` sob demanda. A sanitização multi-turno
|
|
209
|
+
(`experimental.chat.messages.transform`) é invariante obrigatória — garante que
|
|
210
|
+
`image_url` / `FilePart` nunca cheguem a um provider textual e não é
|
|
211
|
+
configurável. O Bifrost permanece opt-in, nunca padrão, conforme o incidente de
|
|
212
|
+
credencial em [SECURITY.md](SECURITY.md).
|
|
213
|
+
|
|
214
|
+
O hook `execute.before` do V2 é o ponto de imposição de sessões somente-leitura
|
|
215
|
+
dessa superfície: o host inclui o agente ativo no evento, um agente somente-leitura
|
|
216
|
+
(`apollo`, `gaia`) registra sua sessão, e o `createEnforcementGuard`
|
|
217
|
+
compartilhado lança para negar `edit`, `write`, `bash`, `task`,
|
|
218
|
+
`hashline_edit` e `pantheon_model`. Ele **não** depende do hook
|
|
219
|
+
`tool.execute.before` do V1, que vive em `src/plugin.ts` e não é carregado
|
|
220
|
+
quando apenas `plugin-v2` está configurado. Quando o host registra o hook
|
|
221
|
+
`permission.evaluate`, ele aplica no V2 a matriz caller/target a todos os itens
|
|
222
|
+
do array `resources` do host para destinos gerenciados pelo Pantheon. Sem o
|
|
223
|
+
registro do hook, a matriz não fica disponível e o host mantém o controle.
|
|
224
|
+
Recursos exclusivamente nativos são repassados sem alteração à política de
|
|
225
|
+
permissões do OpenCode; pedidos mistos (nativos/Pantheon) ou com vários destinos
|
|
226
|
+
são negados.
|
|
227
|
+
Para destinos Pantheon, a política exige uma chamada nativa `subagent` cujo
|
|
228
|
+
session ID, message ID e tool-call ID no `source` coincidam com o evento do host
|
|
229
|
+
`tool.execute.before`; também confirma que a sessão não tem `parentID`. O campo
|
|
230
|
+
`permission.evaluate.agent`, sozinho, não identifica o chamador. Origins
|
|
231
|
+
ausentes, expirados, repetidos ou incompatíveis são negados. A canary no
|
|
232
|
+
OpenCode v2.0.29 admite Zeus→Apollo na raiz e nega dispatches inválidos ou
|
|
233
|
+
originados em uma filha; veja o [relatório de F4A](bench/results/f4a-v229-admission-identity-2026-10-14.md).
|
|
234
|
+
Uma negação explícita do host é final, e dados de recursos ausentes ou
|
|
235
|
+
desconhecidos são negados por padrão. O `execute.after` do
|
|
236
|
+
V2 executa a cadeia de resultados concluídos `task-result-guard` →
|
|
237
|
+
`context-sandbox` → `read-enhancer`; eventos de erro permanecem inalterados.
|
|
238
|
+
|
|
239
|
+
#### Leitura bounded do workspace (F3b)
|
|
240
|
+
|
|
241
|
+
No OpenCode v2.0.29, o plugin V2 pode registrar `pantheon_bounded_read` quando
|
|
242
|
+
o host oferece as APIs nativas de permissão e sessão. Só uma sessão root do
|
|
243
|
+
Zeus pode usá-la. Cada chamada pede ao host permissão `read` para um arquivo
|
|
244
|
+
relativo exato do workspace, com escopo de persistência vazio; o conteúdo só é
|
|
245
|
+
lido após aprovação e passa pelo scanner de segredos fail-closed existente.
|
|
246
|
+
Os limites são duas chamadas e dois arquivos distintos, 400 linhas e 32 KiB
|
|
247
|
+
por mensagem do assistant. Travessia de diretórios, symlinks, diretórios,
|
|
248
|
+
escopos sensíveis, formatos binários/mídia reconhecidos e falhas do scanner são
|
|
249
|
+
negados. O escopo suportado é um workspace local sem escritores concorrentes;
|
|
250
|
+
isso não promete isolamento contra filesystem adversarial nem classificação
|
|
251
|
+
binária do arquivo inteiro. Evidência host-backed:
|
|
252
|
+
[`bench/results/f3b-v229-bounded-read-2026-10-15.md`](bench/results/f3b-v229-bounded-read-2026-10-15.md).
|
|
253
|
+
|
|
254
|
+
Toda ferramenta V2 declara um schema `output`. O OpenCode 2.0.x exige que a
|
|
255
|
+
declaração e o resultado resolvido concordem nos dois sentidos, então uma
|
|
256
|
+
ferramenta sem declaração — ou que retorne `output` sem declará-lo — falha em
|
|
257
|
+
toda chamada. Os recursos V2 sem suporte são `legacy-hooks` (a superfície de
|
|
258
|
+
hooks específica do V1), `catalog-transform`, `integration-transform`,
|
|
259
|
+
`skill-transform` e `goal-tools`.
|
|
142
260
|
|
|
143
261
|
O pacote expõe os dois contratos como exports importáveis:
|
|
144
262
|
`pantheon-opencode/plugin` (V1), `pantheon-opencode/plugin-v2` (V2) e
|
|
@@ -158,26 +276,68 @@ npx pantheon-opencode init --opencode-version v2
|
|
|
158
276
|
npx pantheon-opencode init --opencode-version auto
|
|
159
277
|
```
|
|
160
278
|
|
|
161
|
-
`--version v1|v2|auto` é aceito como a grafia antiga do seletor
|
|
162
|
-
depois de `init`. `auto`
|
|
163
|
-
|
|
164
|
-
terminando em `opencode2` seleciona V2;
|
|
165
|
-
|
|
279
|
+
`auto` é o padrão. `--version v1|v2|auto` é aceito como a grafia antiga do seletor
|
|
280
|
+
quando usado depois de `init`. `auto` resolve a geração a partir do host nesta
|
|
281
|
+
ordem: um `OPENCODE_VERSION=v1|v2` explícito vence; caso contrário, um
|
|
282
|
+
`OPENCODE_BIN` terminando em `opencode2` seleciona V2; caso contrário o binário
|
|
283
|
+
do host é consultado com `--version` e uma major >= 2 seleciona V2. Qualquer
|
|
284
|
+
outro caso — uma sonda ilegível, um banner não interpretável, ou um banner
|
|
285
|
+
cujos tokens de versão se contradizem sem um nome de ferramenta que desfaça o
|
|
286
|
+
empate — avisa uma vez e volta para V1, porque uma entrada de diretório em
|
|
287
|
+
`plugins` plural em um host 1.x desconhecido perde o plugin inteiro.
|
|
288
|
+
|
|
289
|
+
A sonda prefere o token que vem logo após o nome da ferramenta, então um token
|
|
290
|
+
de runtime antes dele (`node v22.1.0 (opencode 1.18.33)`) ou uma data de build
|
|
291
|
+
no final (`opencode v1.18.33 built 2026.10.04`) não conseguem virar a geração.
|
|
292
|
+
O instalador remove referências Pantheon das duas formas de config antes de
|
|
166
293
|
gravar apenas o registro Pantheon selecionado. Entradas de terceiros não são
|
|
167
294
|
convertidas nem reivindicadas por essa regra.
|
|
168
295
|
|
|
169
|
-
O relatório `pantheon_cost`, disponível nos plugins V1 e V2,
|
|
170
|
-
|
|
171
|
-
`PANTHEON_COST_DB=/caminho/absoluto/para/opencode.db
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
296
|
+
O relatório `pantheon_cost`, disponível nos plugins V1 e V2, resolve o banco por
|
|
297
|
+
CAMINHO, nesta ordem: um `dbPath` explícito fornecido pelo chamador da
|
|
298
|
+
ferramenta, depois `PANTHEON_COST_DB=/caminho/absoluto/para/opencode.db`,
|
|
299
|
+
depois `OPENCODE_DB`, e por fim o padrão do XDG `opencode.db`. Não há nome de
|
|
300
|
+
arquivo por versão nessa cadeia: `opencode-v2.db` não é um banco de um host 2.x
|
|
301
|
+
— é o nome que um sandbox dá ao próprio banco de estado via `OPENCODE_DB`.
|
|
302
|
+
|
|
303
|
+
A distinção v1/v2 é o SCHEMA DETECTADO, não o nome do arquivo. O relatório
|
|
304
|
+
procura as tabelas `message` e `session_message` e lê aquele que o banco aberto
|
|
305
|
+
realmente tiver, porque um banco migrado carrega as duas famílias ao mesmo
|
|
306
|
+
tempo. `PANTHEON_OPENCODE_VERSION=v1|v2` não seleciona arquivo nenhum: apenas
|
|
307
|
+
estreita um conjunto já detectado para uma família de tabelas, e falha rápido
|
|
308
|
+
quando o valor não é `v1` nem `v2` ou quando a família pedida não existe lá.
|
|
309
|
+
Sem a variável, todas as famílias detectadas são lidas. Um banco sem nenhuma
|
|
310
|
+
das duas tabelas volta como erro acionável (`CORRUPT_DATA`), e um ledger que
|
|
311
|
+
existe mas não produz tokens legíveis como `UNSUPPORTED` — nunca como um
|
|
312
|
+
relatório vazio com sucesso.
|
|
176
313
|
|
|
177
314
|
O instalador continua gravando as configurações de compatibilidade exigidas
|
|
178
315
|
pelo host OpenCode selecionado, como `experimental.subagent_depth`; isso não
|
|
179
316
|
converte um plugin V1 em V2 nem dá hooks V1 ao V2.
|
|
180
317
|
|
|
318
|
+
O Pantheon não define mais um teto de passos para os agentes. No OpenCode 2 o
|
|
319
|
+
campo `steps` é opcional e não tem default: ausente significa que o host não
|
|
320
|
+
aplica nenhum limite nativo. Uma config escrita antes dessa mudança ainda
|
|
321
|
+
carrega o valor antigo, e o caminho de instalação v2 o remove de todos os
|
|
322
|
+
agentes que o Pantheon gerencia — um agente definido por você nunca é tocado,
|
|
323
|
+
e o bloco V1 singular `agent`, em retirada, é deixado intacto. Rode o
|
|
324
|
+
instalador uma vez para limpar um valor antigo de uma config existente:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
npx pantheon-opencode init --opencode-version=v2
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
O controle de contexto não é uma configuração do Pantheon. Qualquer orçamento
|
|
331
|
+
que um agente terá vem das settings de compactação do próprio host OpenCode,
|
|
332
|
+
e o Pantheon não as define.
|
|
333
|
+
|
|
334
|
+
Quando um bloco V1 `agent` e um bloco V2 `agents` coexistem — o que acontece
|
|
335
|
+
em qualquer `opencode.json` já instalado — a conversão V1→V2 mescla os dois em
|
|
336
|
+
vez de deixar um substituir o outro. O bloco V2 é a base, os campos
|
|
337
|
+
gerenciados que vêm do V1 sobrescrevem, e os seus próprios campos são
|
|
338
|
+
preservados, com a mesma precedência que o instalador já aplica em outros
|
|
339
|
+
pontos. A ordem das chaves não muda o resultado.
|
|
340
|
+
|
|
181
341
|
## Atualizando entre releases (beta.5+)
|
|
182
342
|
|
|
183
343
|
Um comando mantém uma instalação existente em dia:
|
|
@@ -200,7 +360,15 @@ pacote. Duas garantias de freshness sustentam isso:
|
|
|
200
360
|
- **Sync de artifacts no postinstall** — depois de qualquer `npm install`, os
|
|
201
361
|
artefatos de cópia (agents, skills, AGENTS.md, commands, scripts MCP,
|
|
202
362
|
payload code-mode) são atualizados automaticamente no config dir existente;
|
|
203
|
-
você nunca precisa re-rodar `init` só para atualizar arquivos.
|
|
363
|
+
você nunca precisa re-rodar `init` só para atualizar arquivos. O config dir
|
|
364
|
+
global recebe o **artefato global** agnóstico de repositório
|
|
365
|
+
(`AGENTS.global.md`: tabela de agentes + regras compartilhadas), enquanto o
|
|
366
|
+
`AGENTS.md` de cada projeto carrega apenas o setup específico do projeto —
|
|
367
|
+
os dois são esculpidos para serem disjuntos (trabalho de latência beta-10),
|
|
368
|
+
então nenhuma regra é paga duas vezes por sessão. A instalação é
|
|
369
|
+
conservadora: conteúdo fora da região gerenciada (regras próprias do
|
|
370
|
+
usuário) é preservado verbatim, um `AGENTS.md` legado totalmente gerado é
|
|
371
|
+
atualizado in place, e qualquer merge é reportado com um aviso.
|
|
204
372
|
- **Detecção de drift** — o instalador grava a versão instalada em
|
|
205
373
|
`.pantheon/install-state.json` e o `doctor` avisa quando o pacote é mais
|
|
206
374
|
novo que o último sync, apontando para o `update`.
|
|
@@ -220,6 +388,10 @@ de PR, push, merge e tag nunca publicam nada, e todos os gates de validação s
|
|
|
220
388
|
fail-closed: somente um PASS explícito autoriza release evidence. Consulte
|
|
221
389
|
[docs/RELEASING.md](docs/RELEASING.md) para detalhes de validação e recuperação.
|
|
222
390
|
|
|
391
|
+
Se a seção de uma versão candidata já existir, atualize as notas com
|
|
392
|
+
`node scripts/versioning.mjs changelog <versão>`; o comando mescla `[Unreleased]`
|
|
393
|
+
na versão indicada sem avançar o número do pacote.
|
|
394
|
+
|
|
223
395
|
A validação mantém cada manifest junto do seu lockfile: o root
|
|
224
396
|
`package.json` + `package-lock.json` e o TUI
|
|
225
397
|
`src/plugins/tui/package.json` + `src/plugins/tui/package-lock.json`. Ambos usam
|
|
@@ -228,39 +400,152 @@ fallback para `npm install`. Uma release carrega um único tarball `.tgz`, calcu
|
|
|
228
400
|
o SHA-256 desse mesmo artefato e vincula o tarball e o GitHub Release ao
|
|
229
401
|
`TARGET_SHA` completo; um segundo pack não é intercambiável.
|
|
230
402
|
|
|
231
|
-
## Validação em sandbox (
|
|
403
|
+
## Validação em sandbox (V2)
|
|
232
404
|
|
|
233
|
-
O `scripts/test-opencode-
|
|
405
|
+
O `scripts/test-opencode-v2-sandbox.sh` valida o pacote instalado
|
|
234
406
|
globalmente como um usuário real dentro de um sandbox isolado (com `HOME`,
|
|
235
407
|
prefix npm e venv próprios) — nunca o ambiente de desenvolvimento. Ele verifica
|
|
236
|
-
OpenCode
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
408
|
+
a perna OpenCode V2: o binário, conectividade MCP, `doctor` e — com
|
|
409
|
+
`--prompts` — uma bateria de prompts cobrindo o recurso `pantheon://agents`,
|
|
410
|
+
memory store/recall, escrita no filesystem e delegação de agente. O gate é
|
|
411
|
+
fail-closed: todo check obrigatório precisa terminar em PASS explícito;
|
|
412
|
+
timeout, falha de auth/rede/provider e pré-requisitos ausentes bloqueiam a
|
|
413
|
+
execução.
|
|
414
|
+
|
|
415
|
+
"V2" aqui se refere somente ao canário de hooks observado em um host OpenCode
|
|
416
|
+
v2.0.18, no qual ao menos um callback testado foi disparado; isso não
|
|
417
|
+
estabelece compatibilidade com o SDK estável `@opencode/plugin@2.0.18` nem com
|
|
418
|
+
o contrato 2.x completo. Esta branch ainda fixa a dependência transitória
|
|
419
|
+
`@opencode-ai/plugin@1.18.30`. Em hosts com `opencode` e `opencode2`, este
|
|
420
|
+
último costuma ser um shim que executa o mesmo binário; a comparação lado a
|
|
421
|
+
lado anterior, portanto, não provava nada sobre o binário em si. O projeto é
|
|
422
|
+
exclusivo V2, portanto há uma única perna.
|
|
242
423
|
|
|
243
424
|
```bash
|
|
244
|
-
scripts/test-opencode-
|
|
245
|
-
scripts/test-opencode-
|
|
246
|
-
scripts/test-opencode-
|
|
247
|
-
scripts/test-opencode-
|
|
248
|
-
scripts/test-opencode-
|
|
425
|
+
scripts/test-opencode-v2-sandbox.sh --prepare # tarball + install + init no sandbox
|
|
426
|
+
scripts/test-opencode-v2-sandbox.sh --run v2 # apenas validação base
|
|
427
|
+
scripts/test-opencode-v2-sandbox.sh --prompts # validação base + bateria de prompts
|
|
428
|
+
scripts/test-opencode-v2-sandbox.sh --rehydrate # sondas offline de rehydration/summary de sessão
|
|
429
|
+
scripts/test-opencode-v2-sandbox.sh --hooks # canário de callbacks de hooks V2
|
|
430
|
+
scripts/test-opencode-v2-sandbox.sh --rehydrate --hooks # executa os dois canários
|
|
431
|
+
scripts/test-opencode-v2-sandbox.sh --reset # limpa a raiz do sandbox
|
|
249
432
|
```
|
|
250
433
|
|
|
251
|
-
Os modos são combináveis (ex.: `--prepare --run
|
|
252
|
-
|
|
253
|
-
|
|
434
|
+
Os modos são combináveis (ex.: `--prepare --run v2 --prompts`). `--rehydrate`
|
|
435
|
+
executa sondas offline de `context_rehydrate` e `context_session_summary`.
|
|
436
|
+
`--hooks` executa um canário de hooks V2 com o binário do sandbox para verificar
|
|
437
|
+
se os callbacks de hooks são disparados; ele não testa os efeitos dos callbacks
|
|
438
|
+
de transform nem comprova o enforcement de segurança `execute.before` do
|
|
439
|
+
Pantheon. Com o par de sondas `--rehydrate --hooks` (sem `--run`, `--prompts` ou
|
|
440
|
+
`--cost`), o canário de hooks ainda é executado se a rehydration falhar, e o
|
|
441
|
+
comando retorna falha em seguida. Esses canários de teste/sandbox não são prova
|
|
442
|
+
de enforcement de segurança do Pantheon. Os binários são resolvidos estritamente
|
|
443
|
+
dentro do prefix npm do sandbox — um sandbox não preparado falha rápido em vez
|
|
444
|
+
de testar silenciosamente a instalação do host.
|
|
254
445
|
|
|
255
446
|
Isso valida somente o sandbox isolado e preparado. Um PASS não prova suporte
|
|
256
447
|
para todo host real nem para configurações de host que não foram exercitadas.
|
|
257
448
|
|
|
449
|
+
## Benchmark de latência (bench/)
|
|
450
|
+
|
|
451
|
+
O `bench/` mede a latência de sessão de ponta a ponta do CLI `opencode`
|
|
452
|
+
instalado com o plugin V2 do repositório — o baseline contra o qual toda
|
|
453
|
+
mudança de performance de uma release deve ser comparada. Executa dois
|
|
454
|
+
cenários N vezes cada, intercalados (não-interativo, um diretório de sandbox
|
|
455
|
+
novo por run), coleta métricas por run do `opencode.db` em modo READ-ONLY
|
|
456
|
+
(tokens root + sessões filhas sem dupla contagem, tool calls por nome, número
|
|
457
|
+
de sessões filhas) e tempos de hook das linhas `[bench]` que o plugin anexa ao
|
|
458
|
+
`hooks.log`:
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
node bench/bin/bench.mjs # 5 runs por cenário (A e B), ~1h
|
|
462
|
+
BENCH_MODEL=opencode-go/glm-5.3-flash node bench/bin/bench.mjs # fixar modelo
|
|
463
|
+
node bench/bin/bench.mjs --runs 1 # smoke: um run por cenário
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Os resultados vão para `bench/results/<label>-<git-sha>.json` (mediana +
|
|
467
|
+
p80 + falhas por cenário); o label padrão é `baseline` e o harness recusa
|
|
468
|
+
sobrescrever um resultado existente, então a identidade do run fica no nome do
|
|
469
|
+
arquivo. O cenário A faz pesquisa web real, então a variância de rede é
|
|
470
|
+
registrada por run.
|
|
471
|
+
|
|
472
|
+
### Perfis de medição (explícitos, nunca inferidos)
|
|
473
|
+
|
|
474
|
+
As instruções são injetadas por duas superfícies: o diretório de config global
|
|
475
|
+
e o diretório do projeto. O harness declara qual delas exercita, porque um
|
|
476
|
+
resultado só significa algo no perfil onde a mudança atua:
|
|
477
|
+
|
|
478
|
+
| `--profile` | `AGENTS.md` global | `AGENTS.md` de projeto | Uso |
|
|
479
|
+
|---|---|---|---|
|
|
480
|
+
| `host` (padrão) | diretório de config do host (ou `--global-agents`) | nenhum — run dirs ficam vazios | a injeção real do host, sem alteração |
|
|
481
|
+
| `double-injection` | diretório de config do host (ou `--global-agents`) | `--project-agents`, escrito em cada run dir | o perfil no repo onde global+projeto se sobrepõem |
|
|
482
|
+
|
|
483
|
+
O padrão mede os cenários A e B. Use `--scenarios B` para isolar o claim
|
|
484
|
+
one-shot de F1; o cenário selecionado ainda roda N vezes (`--runs 5` por
|
|
485
|
+
padrão).
|
|
486
|
+
|
|
487
|
+
```bash
|
|
488
|
+
# braço candidato: artefato global carveado + artefato de projeto carveado
|
|
489
|
+
node bench/bin/bench.mjs --runs 5 --scenarios B --profile double-injection \
|
|
490
|
+
--global-agents AGENTS.global.md --project-agents AGENTS.md --label f1-candidate
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Cada braço registra, por run e lido do banco, a identidade (caminho, bytes,
|
|
494
|
+
sha256) de cada arquivo de instrução que a sessão de fato carregou
|
|
495
|
+
(`instruction_state` + `instruction_blob`) — a prova de fidelidade de que o
|
|
496
|
+
que foi medido é o que foi gerado. Um claim só pode se apoiar num run cuja
|
|
497
|
+
provenance mostre que os artefatos global **e** de projeto pretendidos foram
|
|
498
|
+
carregados.
|
|
499
|
+
|
|
500
|
+
### Sinal vs ruído
|
|
501
|
+
|
|
502
|
+
Wall time é pista, não critério: o spread same-day chega a ~8× no cenário A e
|
|
503
|
+
~13× no B. Um efeito só é **confirmado** quando excede o spread same-day (ou
|
|
504
|
+
exige N maior); caso contrário é registrado como **inconclusivo**. Prefira
|
|
505
|
+
medianas de tokens, bem mais estáveis. O wall do cenário A não é métrica de
|
|
506
|
+
claim — ele faz pesquisa web real, então a variância de rede domina.
|
|
507
|
+
|
|
508
|
+
### Proxy do 1º request e evidência de F1
|
|
509
|
+
|
|
510
|
+
O payload de instruções injetado só incide no primeiro request, então o
|
|
511
|
+
`tokens.input` total da árvore (somado em todo turno) é dominado pela variância
|
|
512
|
+
de duração da sessão. Cada run também registra `firstRequest` — o
|
|
513
|
+
`tokens.input` + `tokens.cache.read` da primeira linha assistant — o proxy que
|
|
514
|
+
isola o payload.
|
|
515
|
+
|
|
516
|
+
Uma rodada intercalada no OpenCode v2.0.29 (C1/K1…C5/K5, N=5/braço) mediu o
|
|
517
|
+
contexto do 1º request em 17555 tokens no controle e 15489 na candidata
|
|
518
|
+
(**−2066, −11,8%**; spread intra-braço de 14 tokens em cada braço). D4 confirmou
|
|
519
|
+
22350 B carregados no controle e 13400 B na candidata (−8950 B, −40,0%); o
|
|
520
|
+
oráculo pré-registrado passou em 5/5 nos dois braços. O efeito no primeiro
|
|
521
|
+
request está confirmado contra o spread intra-braço; a aceitação final de F1
|
|
522
|
+
aguarda revisão do Themis. O input total da árvore caiu da mediana de 47594 para
|
|
523
|
+
38253 tokens, mas os ranges se sobrepõem e a hipótese de ≤30k não foi atingida.
|
|
524
|
+
As medianas de wall foram 30,078 s e 24,130 s, com spread alto; input total e
|
|
525
|
+
wall permanecem **inconclusivos**. Não há claim de ganho de wall ou custo
|
|
526
|
+
monetário. Detalhes e artefatos por run:
|
|
527
|
+
`bench/results/f1-di-v229-interleaved-2026-10-14.md`. O par sequencial anterior
|
|
528
|
+
permanece somente como evidência de apoio em
|
|
529
|
+
`bench/results/f1-di-v229-clean-2026-10-14.md`. As rodadas exploratórias
|
|
530
|
+
anteriores foram preservadas separadamente em
|
|
531
|
+
`bench/results/f1-double-injection.md` e
|
|
532
|
+
`bench/results/f1-di-v229-preliminary-2026-10-14.md`.
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
## Cobertura TypeScript do Plugin V2
|
|
536
|
+
|
|
537
|
+
`npm run coverage:plugin-v2` executa a suíte `tests/pantheon/*.test.ts` com a
|
|
538
|
+
cobertura nativa do Node habilitada para source maps e exige pelo menos 80% de
|
|
539
|
+
cobertura de linhas somente para `src/plugin-v2.ts`. Requer Node `v24.15.0`;
|
|
540
|
+
coberturas de branches e funções são informativas, não gates. Isso não é uma
|
|
541
|
+
alegação de cobertura do repositório inteiro.
|
|
542
|
+
|
|
258
543
|
Variáveis de ambiente:
|
|
259
544
|
|
|
260
545
|
| Variável | Padrão | Finalidade |
|
|
261
546
|
|----------|---------|---------|
|
|
262
547
|
| `PANTHEON_SANDBOX_ROOT` | `~/pantheon-sandbox` | Raiz do sandbox (recusada se insegura para `--reset`) |
|
|
263
|
-
| `OPENCODE_V1_SPEC` | `opencode-ai@1.18.18` |
|
|
548
|
+
| `OPENCODE_V1_SPEC` | `opencode-ai@1.18.18` | Configura somente o plugin V1; o runner de sandbox exclusivo V2 não consome nem oferece suporte a essa variável |
|
|
264
549
|
| `OPENCODE_V2_SPEC` | `@opencode-ai/cli@beta` | Spec npm que fornece o binário `opencode2` |
|
|
265
550
|
| `PANTHEON_SANDBOX_MODEL` | `opencode-go/mimo-v2.5` | Modelo usado pelo init e pelos prompts |
|
|
266
551
|
| `PANTHEON_PROMPT_TIMEOUT` | `300` | Timeout por prompt em segundos |
|
|
@@ -271,7 +556,7 @@ preparado.
|
|
|
271
556
|
|
|
272
557
|
### Divergência intencional do memory MCP
|
|
273
558
|
|
|
274
|
-
`scripts/
|
|
559
|
+
`scripts/memory_mcp.py` e `src/mcp/memory_mcp.py` são
|
|
275
560
|
intencionalmente diferentes. A cópia independente em `scripts/` mantém o
|
|
276
561
|
contrato leve de `memory_*`; a cópia instalada em `src/mcp/` também expõe o
|
|
277
562
|
schema opcional de codemap e `code_index`, `code_query` e `code_neighbors`. As
|
|
@@ -295,10 +580,10 @@ uma issue ou pull request.
|
|
|
295
580
|
|
|
296
581
|
## Citação e DOI
|
|
297
582
|
|
|
298
|
-
O Pantheon é distribuído sob a [Licença MIT](LICENSE).
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
[CITATION.cff](CITATION.cff).
|
|
583
|
+
O Pantheon é distribuído sob a [Licença MIT](LICENSE). Cite o
|
|
584
|
+
[DOI conceitual do Zenodo](https://doi.org/10.5281/zenodo.22650136), que sempre
|
|
585
|
+
resolve para a última release arquivada; cada release também tem seu próprio
|
|
586
|
+
version DOI. Os metadados de citação também estão em [CITATION.cff](CITATION.cff).
|
|
302
587
|
|
|
303
588
|
Repositório canônico: <https://github.com/ils15/pantheon-opencode>
|
|
304
589
|
|
package/bin/pantheon-init.mjs
CHANGED
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
* installOpenCode() from scripts/install/opencode.mjs.
|
|
9
9
|
*
|
|
10
10
|
* Dual-version install (Phase 3): the generated config is V1-shaped and valid
|
|
11
|
-
* under BOTH OpenCode V1 (`opencode` 1.18.x) and V2 (`opencode2
|
|
12
|
-
*
|
|
11
|
+
* under BOTH OpenCode V1 (`opencode` 1.18.x) and V2 (`opencode2`, OpenCode 2.x —
|
|
12
|
+
* `opencode2 --version` prints "opencode v2.0.22"; an early 2.x prerelease
|
|
13
|
+
* printed "0.0.0-next-17444", which is history and not a host observation).
|
|
14
|
+
* V2 reads the same config locations and normalizes V1
|
|
13
15
|
* fields in memory — no native V2 conversion. `--version v2` labels the
|
|
14
16
|
* install for the operator; state isolation is a runtime concern
|
|
15
17
|
* (OPENCODE_DB ~/.local/share/opencode/opencode-v2.db, service port 49375).
|
|
@@ -54,6 +56,9 @@ function printUsage() {
|
|
|
54
56
|
console.log(' npx pantheon-opencode init --components agents,skills,instructions')
|
|
55
57
|
console.log(' npx pantheon-opencode init --opencode-version v1|v2|auto')
|
|
56
58
|
console.log(' npx pantheon-opencode init --preset <name> # Install and activate model preset')
|
|
59
|
+
console.log(
|
|
60
|
+
' npx pantheon-opencode init --merge-dev-config <path> # Merge a dev config (off by default)',
|
|
61
|
+
)
|
|
57
62
|
console.log(' npx pantheon-opencode set-tier <name> # Set active model preset (global)')
|
|
58
63
|
console.log(
|
|
59
64
|
' npx pantheon-opencode update [--stable] # Update package + re-run init (default: beta channel)',
|
|
@@ -287,6 +292,7 @@ async function main() {
|
|
|
287
292
|
'--version',
|
|
288
293
|
'--opencode-version',
|
|
289
294
|
'--components',
|
|
295
|
+
'--merge-dev-config',
|
|
290
296
|
])
|
|
291
297
|
for (let i = 1; i < args.length; i++) {
|
|
292
298
|
const arg = args[i]
|
|
@@ -368,6 +374,22 @@ async function main() {
|
|
|
368
374
|
}
|
|
369
375
|
}
|
|
370
376
|
|
|
377
|
+
// --merge-dev-config <path> opts IN to merging a contributor's personal
|
|
378
|
+
// OpenCode config into the generated one. Only third-party plugin/provider/
|
|
379
|
+
// compaction entries are merged; Pantheon-owned entries are always stripped.
|
|
380
|
+
// Absent this flag no repository-root config is read (product defaults come
|
|
381
|
+
// from the installer code, never from a dev checkout).
|
|
382
|
+
const mergeDevConfigIndex = args.indexOf('--merge-dev-config')
|
|
383
|
+
const inlineMergeDevConfig = args.find((arg) => arg.startsWith('--merge-dev-config='))
|
|
384
|
+
const mergeDevConfigOpt =
|
|
385
|
+
mergeDevConfigIndex >= 0
|
|
386
|
+
? (args[mergeDevConfigIndex + 1] ?? null)
|
|
387
|
+
: (inlineMergeDevConfig?.split('=', 2)[1] ?? null)
|
|
388
|
+
if (mergeDevConfigIndex >= 0 && mergeDevConfigOpt === null) {
|
|
389
|
+
console.error('❌ --merge-dev-config requires a file path')
|
|
390
|
+
process.exit(1)
|
|
391
|
+
}
|
|
392
|
+
|
|
371
393
|
const components = requestedComponents ?? [
|
|
372
394
|
'agents',
|
|
373
395
|
'skills',
|
|
@@ -402,7 +424,8 @@ async function main() {
|
|
|
402
424
|
model: modelOpt,
|
|
403
425
|
smallModel: smallModelOpt,
|
|
404
426
|
preset: presetOpt,
|
|
405
|
-
version: versionOpt ?? '
|
|
427
|
+
version: versionOpt ?? 'auto',
|
|
428
|
+
mergeDevConfig: mergeDevConfigOpt,
|
|
406
429
|
})
|
|
407
430
|
} catch (err) {
|
|
408
431
|
if (err?.message === 'Canceled') {
|
|
@@ -15,7 +15,13 @@ agent: "zeus"
|
|
|
15
15
|
## Layers
|
|
16
16
|
|
|
17
17
|
### Layer 1 — Heuristic Scan
|
|
18
|
-
|
|
18
|
+
Resolve the installed helper first (do not assume the current project contains
|
|
19
|
+
Pantheon source). Check, in order: `$OPENCODE_CONFIG_DIR/.opencode/scripts/`,
|
|
20
|
+
`$OPENCODE_CONFIG_DIR/scripts/`, `${XDG_CONFIG_HOME:-$HOME/.config}/opencode/scripts/`,
|
|
21
|
+
`$HOME/.opencode/scripts/`, `.opencode/scripts/`, then
|
|
22
|
+
`$(npm root -g)/pantheon-opencode/scripts/`. Resolve the first existing file to
|
|
23
|
+
an absolute path and run `python3 "$helper" --path="$PWD"`; if none exists,
|
|
24
|
+
report the helper as missing and stop Layer 1 rather than claiming it passed.
|
|
19
25
|
Zero tokens, <2s. Checks: ruff, biome, anti-pattern slop, anti-overengineering (YAGNI), hash-anchored edits. Returns score 0-100 + APPROVED/BLOCKING.
|
|
20
26
|
|
|
21
27
|
### Layer 2 — Themis Deep Review
|
|
@@ -15,8 +15,15 @@ Structured, checkpointed workflow for complex multi-step tasks spanning multiple
|
|
|
15
15
|
## Workflow
|
|
16
16
|
|
|
17
17
|
```
|
|
18
|
-
Phase 0:
|
|
19
|
-
└─
|
|
18
|
+
Phase 0: PLAN AND APPROVAL
|
|
19
|
+
└─ @athena returns the complete, detailed Markdown plan to Zeus
|
|
20
|
+
└─ Zeus publishes the full plan as a normal message in the main conversation (not only in the child-agent transcript)
|
|
21
|
+
└─ GATE 1: open the approval UI only after that plan message is visible; never bundle or reverse the two
|
|
22
|
+
└─ If the runtime cannot guarantee that order, ask for approval in plain text after the plan and wait
|
|
23
|
+
└─ Wait for explicit approval or requested changes
|
|
24
|
+
└─ For requested changes, redisplay the entire revised plan and repeat Gate 1
|
|
25
|
+
└─ Do not start discovery or implementation before approval
|
|
26
|
+
└─ After approval, persist the approved plan as PLAN.md through the artifact workflow
|
|
20
27
|
|
|
21
28
|
Phase 1: DISCOVERY
|
|
22
29
|
└─ @apollo maps relevant codebase areas → DISCOVERY.md
|
|
@@ -44,7 +51,11 @@ Usage: --resume <slug> | --status <slug> | --list
|
|
|
44
51
|
|
|
45
52
|
## Full-Auto Mode (`--full-auto`)
|
|
46
53
|
|
|
47
|
-
> ⚠️
|
|
54
|
+
> ⚠️ Automates only eligible review gates. Gate 1 and commit/deploy gates still require approval.
|
|
55
|
+
|
|
56
|
+
`--full-auto` does not hide the plan or skip Gate 1: Zeus still displays the
|
|
57
|
+
complete plan in the main conversation and waits for explicit approval before
|
|
58
|
+
discovery or implementation. It only affects the later gates described below.
|
|
48
59
|
|
|
49
60
|
**Themis auto-approves non-blocking reviews** — only stops on **BLOCKING** verdict. No waiting between phases. Checkpoints saved at every boundary.
|
|
50
61
|
|