atlas-workflow 0.9.2 → 0.9.3
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/README.md +5 -2
- package/VERSION +1 -1
- package/build/bump-version.mjs +6 -21
- package/build/cli/atlas-init.mjs +92 -5
- package/hosts/opencode/.opencode/atlas/VERSION +1 -1
- package/hosts/opencode/.opencode/atlas/orchestrator/README.md +1 -1
- package/hosts/opencode/.opencode/atlas/orchestrator/references/host-adapters.md +13 -12
- package/hosts/opencode/.opencode/atlas/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +2 -0
- package/hosts/opencode/.opencode/atlas/packages/mcp-server/README.md +1 -1
- package/hosts/opencode/.opencode/atlas/packages/mcp-server/package.json +1 -1
- package/hosts/opencode/.opencode/atlas/packages/mcp-server/server.js +69 -7
- package/hosts/opencode/.opencode/skills/atlas-workflow-orchestrator/SKILL.md +2 -0
- package/hosts/pi/atlas/VERSION +1 -1
- package/hosts/pi/atlas/orchestrator/README.md +1 -1
- package/hosts/pi/atlas/orchestrator/references/host-adapters.md +13 -12
- package/hosts/pi/atlas/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +2 -0
- package/hosts/pi/atlas/packages/mcp-server/README.md +1 -1
- package/hosts/pi/atlas/packages/mcp-server/package.json +1 -1
- package/hosts/pi/atlas/packages/mcp-server/server.js +69 -7
- package/hosts/pi/skills/atlas-workflow-orchestrator/SKILL.md +2 -0
- package/hosts/zcode/.zcode-plugin/plugin.json +27 -0
- package/hosts/zcode/agents/atlas-direct-execute.md +31 -0
- package/hosts/zcode/agents/atlas-findings-repair.md +39 -0
- package/hosts/zcode/agents/atlas-plan-execute.md +33 -0
- package/hosts/zcode/agents/atlas-slice-review.md +27 -0
- package/hosts/zcode/agents/atlas-task-validator.md +138 -0
- package/hosts/zcode/packages/mcp-server/README.md +29 -0
- package/hosts/zcode/packages/mcp-server/VERSION +1 -0
- package/hosts/zcode/packages/mcp-server/package.json +15 -0
- package/hosts/zcode/packages/mcp-server/server.js +3897 -0
- package/hosts/zcode/packages/orchestrator/README.md +270 -0
- package/hosts/zcode/packages/orchestrator/commands/workflow.md +37 -0
- package/hosts/zcode/packages/orchestrator/defaults/paths.md +21 -0
- package/hosts/zcode/packages/orchestrator/references/host-adapters.md +106 -0
- package/hosts/zcode/packages/orchestrator/references/qa_s13_matrix.md +141 -0
- package/hosts/zcode/packages/orchestrator/references/subagent_dispatch.md +42 -0
- package/hosts/zcode/packages/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +391 -0
- package/hosts/zcode/packages/templates/BACKLOG_MESTRE_TEMPLATE.md +855 -0
- package/hosts/zcode/packages/templates/BOUNDARY_PRD_PLAN.md +93 -0
- package/hosts/zcode/packages/templates/PERGUNTAS_EM_ABERTO_TEMPLATE.md +139 -0
- package/hosts/zcode/packages/templates/PLAN_TEMPLATE.md +146 -0
- package/hosts/zcode/packages/templates/PRD_TEMPLATE.md +150 -0
- package/hosts/zcode/packages/templates/STATE_FILE_SCHEMA.md +56 -0
- package/hosts/zcode/skills/_shared/references/stack-profiles.md +36 -0
- package/hosts/zcode/skills/_shared/scripts/document_quality.mjs +252 -0
- package/hosts/zcode/skills/atlas-backlog-generator/SKILL.md +93 -0
- package/hosts/zcode/skills/atlas-backlog-generator/agents/openai.yaml +4 -0
- package/hosts/zcode/skills/atlas-direct-execute/SKILL.md +221 -0
- package/hosts/zcode/skills/atlas-direct-execute/agents/openai.yaml +7 -0
- package/hosts/zcode/skills/atlas-findings-repair/SKILL.md +158 -0
- package/hosts/zcode/skills/atlas-findings-repair/agents/openai.yaml +7 -0
- package/hosts/zcode/skills/atlas-plan-execute/SKILL.md +175 -0
- package/hosts/zcode/skills/atlas-plan-execute/agents/openai.yaml +7 -0
- package/hosts/zcode/skills/atlas-plan-execute/references/plan-contract.md +88 -0
- package/hosts/zcode/skills/atlas-plan-execute/references/quality-gates.md +60 -0
- package/hosts/zcode/skills/atlas-plan-execute/scripts/check_budget_state.py +96 -0
- package/hosts/zcode/skills/atlas-plan-execute/scripts/extract_plan_contract.py +191 -0
- package/hosts/zcode/skills/atlas-plan-execute/scripts/validate_gate_result.py +56 -0
- package/hosts/zcode/skills/atlas-plan-handoff/SKILL.md +183 -0
- package/hosts/zcode/skills/atlas-plan-handoff/agents/openai.yaml +7 -0
- package/hosts/zcode/skills/atlas-prd-interview/SKILL.md +82 -0
- package/hosts/zcode/skills/atlas-prd-interview/agents/openai.yaml +7 -0
- package/hosts/zcode/skills/atlas-slice-review/SKILL.md +156 -0
- package/hosts/zcode/skills/atlas-slice-review/agents/openai.yaml +4 -0
- package/hosts/zcode/skills/atlas-slice-review/references/review-contract.md +58 -0
- package/hosts/zcode/skills/atlas-slice-review/references/scenario-lenses.md +57 -0
- package/hosts/zcode/skills/atlas-slice-review/scripts/classify_findings.mjs +60 -0
- package/hosts/zcode/skills/atlas-slice-review/scripts/classify_findings.py +24 -0
- package/hosts/zcode/skills/atlas-slice-review/scripts/extract_review_slice.py +158 -0
- package/hosts/zcode/skills/atlas-sprint-prd-generator/SKILL.md +77 -0
- package/hosts/zcode/skills/atlas-sprint-prd-generator/agents/openai.yaml +7 -0
- package/hosts/zcode/skills/atlas-task-validator/SKILL.md +173 -0
- package/hosts/zcode/skills/atlas-task-validator/agents/openai.yaml +7 -0
- package/hosts/zcode/skills/atlas-workflow-orchestrator/SKILL.md +391 -0
- package/package.json +1 -1
- package/plugins/atlas-workflow-orchestrator/.codex-plugin/plugin.json +1 -1
- package/plugins/atlas-workflow-orchestrator/VERSION +1 -1
- package/plugins/atlas-workflow-orchestrator/orchestrator/README.md +1 -1
- package/plugins/atlas-workflow-orchestrator/orchestrator/references/host-adapters.md +13 -12
- package/plugins/atlas-workflow-orchestrator/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +2 -0
- package/plugins/atlas-workflow-orchestrator/packages/mcp-server/README.md +1 -1
- package/plugins/atlas-workflow-orchestrator/packages/mcp-server/package.json +1 -1
- package/plugins/atlas-workflow-orchestrator/packages/mcp-server/server.js +69 -7
- package/plugins/atlas-workflow-orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +2 -0
|
@@ -283,23 +283,81 @@ const HOST_ADAPTERS = {
|
|
|
283
283
|
},
|
|
284
284
|
antigravity: {
|
|
285
285
|
label: 'Antigravity',
|
|
286
|
+
// Antigravity não tem skill loader nativo em subagentes — o SKILL.md completo
|
|
287
|
+
// DEVE ser embutido no Prompt de cada invoke_subagent (via define_subagent como
|
|
288
|
+
// system_prompt ou diretamente no Prompt). Nunca despachar subagente sem SKILL.md
|
|
289
|
+
// injetado, pois o subagente não carregará o contrato e o pipeline vai impasse.
|
|
290
|
+
//
|
|
291
|
+
// Fluxo para fases de execução/validação (executor, validator, repair, review):
|
|
292
|
+
// 1. define_subagent(name: "<atlas-exec>", system_prompt: "<SKILL.MD completo>")
|
|
293
|
+
// 2. invoke_subagent(Subagents: [{TypeName: "<atlas-exec>", Role: "<papel>",
|
|
294
|
+
// Prompt: "<state_path ou plan_path>",
|
|
295
|
+
// Workspace: "branch"}])
|
|
296
|
+
// — invoke_subagent é BLOQUEANTE por design: não polling, não background.
|
|
297
|
+
// — Workspace: "branch" garante isolamento de contexto (fronteira G4/G9).
|
|
298
|
+
//
|
|
299
|
+
// Fases documentais (PRD, entrevista, plano) NÃO usam subagente — o orquestrador
|
|
300
|
+
// conduz no fio principal; define_subagent não é chamado para essas fases.
|
|
286
301
|
subagent_dispatch: {
|
|
287
|
-
mechanism: 'define_subagent(name, system_prompt) + invoke_subagent(Subagents)',
|
|
288
|
-
example: 'define_subagent(name: "atlas-task-validator", system_prompt: "<
|
|
289
|
-
registration: '
|
|
302
|
+
mechanism: 'define_subagent(name, system_prompt) + invoke_subagent(Subagents: [{TypeName, Role, Prompt, Workspace}])',
|
|
303
|
+
example: 'define_subagent(name: "atlas-task-validator", system_prompt: "<SKILL.MD completo do atlas-task-validator>") seguido de invoke_subagent(Subagents: [{TypeName: "atlas-task-validator", Role: "Validador frio", Prompt: "<state_path>", Workspace: "branch"}])',
|
|
304
|
+
registration: 'define_subagent dinâmico por sessão — o SKILL.md canônico é passado como system_prompt; sem pré-registro persistente',
|
|
305
|
+
// Sem loader nativo: o SKILL.md DEVE ser embutido no system_prompt do define_subagent.
|
|
306
|
+
// Não usar TypeName: "self" sem injetar o SKILL.md — o subagente herdaria o contexto
|
|
307
|
+
// do orquestrador e violaria o isolamento frio (G4/G9).
|
|
308
|
+
skill_loading: 'embed_in_system_prompt',
|
|
290
309
|
},
|
|
291
310
|
validator_dispatch: {
|
|
292
311
|
dispatcher: 'orchestrator',
|
|
293
312
|
join: {
|
|
294
313
|
sync: 'self_evident',
|
|
295
314
|
confidence: 'high',
|
|
296
|
-
mechanism: 'invoke_subagent bloqueante por design do host',
|
|
315
|
+
mechanism: 'invoke_subagent bloqueante por design do host — sem polling, sem callback',
|
|
297
316
|
},
|
|
298
317
|
},
|
|
299
|
-
question_prompt:
|
|
318
|
+
// question_prompt: usado pela atlas-prd-interview para fazer perguntas ao usuário.
|
|
319
|
+
// No Antigravity, usar ask_question (ferramenta nativa de perguntas interativas).
|
|
320
|
+
// IMPORTANTE — resume_after_interview: após receber respostas via ask_question,
|
|
321
|
+
// persistir no PRD e RETOMAR O PIPELINE IMEDIATAMENTE sem nova confirmação.
|
|
322
|
+
// Nunca aguardar input adicional do usuário entre fases — viola fire-and-continue.
|
|
323
|
+
question_prompt: {
|
|
324
|
+
mechanism: 'ask_question',
|
|
325
|
+
mode: 'structured',
|
|
326
|
+
max_questions: 4,
|
|
327
|
+
options_per_question: 3,
|
|
328
|
+
persistence: 'prd_after_each_round',
|
|
329
|
+
resume_after_interview: 'automatic',
|
|
330
|
+
},
|
|
300
331
|
todo_tool: null,
|
|
301
332
|
hooks: { supported: false, mechanism: null },
|
|
302
333
|
capabilities_flags: { subagent_available: true, mcp_available: true, todo_available: false },
|
|
334
|
+
// self_evident: MCP nativo + invoke_subagent bloqueante provados pelo boot do host.
|
|
335
|
+
// Não exige host_capabilities report (igual claude/codex/opencode).
|
|
336
|
+
prereq_policy: 'self_evident',
|
|
337
|
+
},
|
|
338
|
+
zcode: {
|
|
339
|
+
label: 'ZCode',
|
|
340
|
+
subagent_dispatch: {
|
|
341
|
+
// ZCode roda no Claude Agent SDK: Agent(subagent_type) nativo e bloqueante.
|
|
342
|
+
// Skills/agents do plugin vivem no bundle (.zcode-plugin) carregado pelo host.
|
|
343
|
+
mechanism: 'Agent(subagent_type)',
|
|
344
|
+
example: 'Agent(subagent_type: "atlas-task-validator", prompt: "<state_path>")',
|
|
345
|
+
registration: 'agents/<name>.md na raiz do plugin (descoberto via .zcode-plugin/plugin.json)',
|
|
346
|
+
},
|
|
347
|
+
validator_dispatch: {
|
|
348
|
+
dispatcher: 'orchestrator',
|
|
349
|
+
join: {
|
|
350
|
+
sync: 'self_evident',
|
|
351
|
+
confidence: 'presumed',
|
|
352
|
+
mechanism: 'Agent(subagent_type) bloqueante por design do host (Claude Agent SDK)',
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
question_prompt: { mechanism: 'AskUserQuestion', mode: 'structured', max_questions: 4, options_per_question: 3, persistence: 'prd_after_each_round' },
|
|
356
|
+
todo_tool: 'TodoWrite',
|
|
357
|
+
hooks: { supported: true, mechanism: '.zcode-plugin/plugin.json (hooks)' },
|
|
358
|
+
// ZCode é clone estrutural do Claude Code (Claude Agent SDK): subagente +
|
|
359
|
+
// MCP-local + TodoWrite nativos. Perfil self_evident — passa PREREQ/JOIN sem report.
|
|
360
|
+
capabilities_flags: { subagent_available: true, mcp_available: true, todo_available: true },
|
|
303
361
|
},
|
|
304
362
|
generic: {
|
|
305
363
|
label: 'Host genérico',
|
|
@@ -367,6 +425,10 @@ const HOST_NAMES = Object.keys(HOST_ADAPTERS);
|
|
|
367
425
|
const HOST_DETECTORS = [
|
|
368
426
|
{ via: 'env:CLAUDE_PLUGIN_ROOT', detect: (env) => (env.CLAUDE_PLUGIN_ROOT ? 'claude' : null) },
|
|
369
427
|
{ via: 'env:CODEX', detect: (env) => (env.CODEX_HOME || env.CODEX_PLUGIN_ROOT ? 'codex' : null) },
|
|
428
|
+
// ZCode (app Electron no Claude Agent SDK) injeta ZCODE_PLUGIN_ROOT ao spawnar o
|
|
429
|
+
// subprocesso MCP do plugin (comprovado no bundle zcode.cjs: interpolação análoga a
|
|
430
|
+
// CLAUDE_PLUGIN_ROOT). Sinal próprio e determinístico — precedência sobre ATLAS_HOST.
|
|
431
|
+
{ via: 'env:ZCODE_PLUGIN_ROOT', detect: (env) => (env.ZCODE_PLUGIN_ROOT ? 'zcode' : null) },
|
|
370
432
|
// opencode/pi não expõem env distintivo garantido no subprocesso MCP (S01).
|
|
371
433
|
// Detecção determinística: o packaging injeta ATLAS_HOST no env do MCP —
|
|
372
434
|
// opencode: opencode.json → mcp.<name>.environment.ATLAS_HOST = "opencode"
|
|
@@ -419,7 +481,7 @@ function capabilities(args = {}) {
|
|
|
419
481
|
// do host com a disponibilidade real reportada pelo caller (`host_capabilities`).
|
|
420
482
|
//
|
|
421
483
|
// Política por host (`prereq_policy`):
|
|
422
|
-
// - 'self_evident' (claude/codex/opencode, default): runtime nativo. Flag essencial
|
|
484
|
+
// - 'self_evident' (claude/codex/opencode/zcode, default): runtime nativo. Flag essencial
|
|
423
485
|
// vem do report quando presente, senão do perfil (otimista justificado: MCP-vivo
|
|
424
486
|
// prova-se no boot; subagente é nativo do host/plugin instalado).
|
|
425
487
|
// - 'must_report' (pi/generic): essencial depende de dep externa (pi) ou de host
|
|
@@ -469,7 +531,7 @@ function checkPrerequisites(args = {}) {
|
|
|
469
531
|
|
|
470
532
|
// Gate JOIN (DEC-SIB-003, SPEC_JOIN_CAPABILITY_S03 §3/§5). Espelha checkPrerequisites:
|
|
471
533
|
// lê validator_dispatch.join do adapter e decide hard-fail por política.
|
|
472
|
-
// - join.sync === 'self_evident' (claude/codex/opencode): host nativo conhecido;
|
|
534
|
+
// - join.sync === 'self_evident' (claude/codex/opencode/zcode): host nativo conhecido;
|
|
473
535
|
// o runtime presume join disponível e NÃO exige report. confidence 'presumed'
|
|
474
536
|
// (claude/opencode) passa, mas é registrado para observabilidade (smoke S13).
|
|
475
537
|
// - join.sync === 'must_report' (pi/generic): fail-closed. Só passa se o caller
|
|
@@ -122,6 +122,7 @@ O pipeline é **fire-and-continue**: uma vez iniciado, o orquestrador avança fa
|
|
|
122
122
|
|
|
123
123
|
A única interação legítima com o usuário é **dentro de uma fase** — o mecanismo estruturado `question_prompt` devolvido por `atlas_capabilities`, usado pela entrevista para resolver ambiguidade de produto. Resolver ambiguidade ≠ pedir permissão pra avançar. Terminada a fase, respostas são persistidas no PRD, gates são reexecutados e o pipeline segue sozinho.
|
|
124
124
|
|
|
125
|
+
|
|
125
126
|
## Papel do orquestrador (fronteira de determinismo pela mutação de código)
|
|
126
127
|
|
|
127
128
|
O orquestrador **coordena a execução**, não implementa código — maestro que aponta cada sub-agent na ordem e espera terminar, **nunca pega o instrumento de código**. A fronteira de determinismo é a **mutação de código** (PRD D10), com **duas fases**:
|
|
@@ -143,6 +144,7 @@ O **mecanismo** varia por host — leia `subagent_dispatch.mechanism`, `.example
|
|
|
143
144
|
|
|
144
145
|
> Ausência de "Agent tool" (host ≠ Claude) **não** é licença pra executar inline — é sinal pra usar o verbo daquele host (Gate G9, qualquer host). Host sem mecanismo de sub-agent já abortou em PREREQ; você nunca chega aqui sem isolamento.
|
|
145
146
|
|
|
147
|
+
|
|
146
148
|
## Protocolo de banner (única comunicação de progresso)
|
|
147
149
|
|
|
148
150
|
O orquestrador comunica progresso **apenas** por **banner de fase de linha única** no formato `▸ atlas: <fase> · <ação> [· <detalhe>]` (PRD D7/D8). Regras:
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "atlas-workflow-orchestrator",
|
|
3
|
+
"version": "0.9.3",
|
|
4
|
+
"description": "Orquestra pipelines de desenvolvimento de features no Atlas (PRD, validação, entrevista, plano, execução, repair, review) e oferece geração explícita de backlog mestre. Bundle único: 9 skills atlas-* + orquestrador + 5 templates canônicos + validator subagente. Pipeline orientado a artefato com gates G1–G11.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Paulo Borini"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"atlas",
|
|
10
|
+
"workflow",
|
|
11
|
+
"orchestration",
|
|
12
|
+
"prd",
|
|
13
|
+
"planning",
|
|
14
|
+
"execution",
|
|
15
|
+
"automation"
|
|
16
|
+
],
|
|
17
|
+
"skills": "./skills/",
|
|
18
|
+
"mcpServers": {
|
|
19
|
+
"atlas-workflow": {
|
|
20
|
+
"command": "node",
|
|
21
|
+
"args": [
|
|
22
|
+
"${ZCODE_PLUGIN_ROOT}/packages/mcp-server/server.js"
|
|
23
|
+
],
|
|
24
|
+
"transport": "stdio"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Executor direto da família Atlas (modo direct). Despachado em contexto isolado pelo orquestrador para implementar um PRD/tarefa escopada sem artefato de plano separado — toda mutação de código acontece aqui, nunca no fio do orquestrador (Gate G9). Primeira ação: carregar a skill completa atlas-direct-execute. Antes do relatório final, escreve o state_path e retorna validator_handoff_required; o orquestrador despacha a validação fria sibling (atlas-task-validator, Gate G4).
|
|
3
|
+
mode: subagent
|
|
4
|
+
temperature: 0.1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Atlas Direct Execute (sub-agent)
|
|
8
|
+
|
|
9
|
+
<!-- MANUTENÇÃO (cross-host): SHIM portável — carrega o SKILL.md real de
|
|
10
|
+
atlas-direct-execute como primeira ação (references/subagent_dispatch.md). Contrato em
|
|
11
|
+
packages/skills/atlas-direct-execute/SKILL.md (fonte única). Versões Codex/opencode/pi
|
|
12
|
+
GERADAS por build/gen-host-agent.mjs. Não copiar o corpo da skill para cá. -->
|
|
13
|
+
|
|
14
|
+
Sub-agent de execução direta despachado pelo orquestrador `atlas-workflow-orchestrator`. Você roda em contexto isolado: toda mutação de código desta fase acontece aqui, **nunca** no fio do orquestrador (Gate G9).
|
|
15
|
+
|
|
16
|
+
## Primeira ação obrigatória
|
|
17
|
+
|
|
18
|
+
Carregue a skill completa `atlas-direct-execute` e siga-a integralmente:
|
|
19
|
+
|
|
20
|
+
- **Claude Code:** invoque a tool `Skill` com `atlas-direct-execute`.
|
|
21
|
+
- **Outros hosts:** use o mecanismo nativo de skills do host para carregar `atlas-direct-execute`.
|
|
22
|
+
|
|
23
|
+
Proibido "agir como a skill" a partir deste resumo — o `SKILL.md` é o contrato real (ledger de obrigações do PRD, gates finitos, reparo limitado). Se não conseguir carregar a skill, aborte com erro explícito; não emule inline.
|
|
24
|
+
|
|
25
|
+
## Input
|
|
26
|
+
|
|
27
|
+
O orquestrador passa o PRD/spec/path escopado e as flags da fase. Use `atlas_run_state` como fonte primária do estado da run.
|
|
28
|
+
|
|
29
|
+
## Validação fria (Gate G4)
|
|
30
|
+
|
|
31
|
+
Antes do relatório final, a validação fria é sempre **sibling**, em todos os hosts: escreva o `state_path`, pare mutações e retorne `validator_handoff_required` para o orquestrador despachar o validador irmão. Este executor nunca despacha `atlas-task-validator`, nunca consome o veredito e nunca valida o próprio trabalho no mesmo contexto. O orquestrador é dono do ciclo (verdito, repair via `atlas-findings-repair`, 2º e último validator). Só `fail` reabre o loop.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Reparador enxuto da família Atlas. Despachado pelo orquestrador apenas após `atlas-task-validator` retornar `fail` em topologia sibling. Corrige findings P0/P1/P2 dentro do boundary da slice sem carregar `atlas-plan-execute`/`atlas-direct-execute` e sem despachar novo validator.
|
|
3
|
+
mode: subagent
|
|
4
|
+
temperature: 0.1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Atlas Findings Repair (sub-agent)
|
|
8
|
+
|
|
9
|
+
<!-- MANUTENÇÃO (cross-host): shim portável. O contrato real vive em
|
|
10
|
+
packages/skills/atlas-findings-repair/SKILL.md. Codex/opencode/pi geram
|
|
11
|
+
registros nativos a partir deste arquivo por build/gen-host-agent.mjs. -->
|
|
12
|
+
|
|
13
|
+
Sub-agent de reparo bounded despachado pelo orquestrador `atlas-workflow-orchestrator`.
|
|
14
|
+
|
|
15
|
+
## Primeira ação obrigatória
|
|
16
|
+
|
|
17
|
+
Carregue a skill completa `atlas-findings-repair` e siga-a integralmente:
|
|
18
|
+
|
|
19
|
+
- **Claude Code:** invoque a tool `Skill` com `atlas-findings-repair`.
|
|
20
|
+
- **Outros hosts:** use o mecanismo nativo de skills do host para carregar `atlas-findings-repair`.
|
|
21
|
+
|
|
22
|
+
Proibido “agir como executor” a partir deste resumo. Se não conseguir carregar a skill, aborte com erro explícito; não substitua por `atlas-plan-execute` nem `atlas-direct-execute`.
|
|
23
|
+
|
|
24
|
+
## Input
|
|
25
|
+
|
|
26
|
+
O orquestrador passa obrigatoriamente `state_path`, findings estruturados, `validator_attempt`, `repair_run_id` e `repair_budget: 1`. Use `atlas_run_state` como fonte primária do estado da run.
|
|
27
|
+
|
|
28
|
+
## Limites
|
|
29
|
+
|
|
30
|
+
- Corrigir apenas findings P0/P1/P2 da slice atual
|
|
31
|
+
- Não despachar validator nem outro subagente
|
|
32
|
+
- Não replanejar
|
|
33
|
+
- Não ampliar escopo
|
|
34
|
+
- Atualizar o `state_path` original em lugar; não trocar o boundary para outro arquivo
|
|
35
|
+
- Consumir IDs/recommendations estruturadas; persistir correlação em `repair_evidence`
|
|
36
|
+
- Preservar `worktree_baseline`, recapturar `worktree_final` e incluir exatamente todo arquivo tocado em `files_changed`; recomputar `head_sha` e `diff_stat`
|
|
37
|
+
- Aceitar somente IDs recebidos; cada arquivo tocado deve estar atribuído a um finding recebido, sem IDs/arquivos extras ou duplicados
|
|
38
|
+
- Devolver `repairs[]` com `finding_id`, arquivos, checks e status
|
|
39
|
+
- Ao terminar, devolver `repair_complete` ou `blocked`
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Executor de plano da família Atlas. Despachado em contexto isolado pelo orquestrador após o plano validado — toda mutação de código (editar, rodar build/testes, commitar) acontece aqui, nunca no fio do orquestrador (Gate G9). Primeira ação: carregar a skill completa atlas-plan-execute. Antes do relatório final, escreve o state_path e retorna validator_handoff_required; o orquestrador despacha a validação fria sibling (atlas-task-validator, Gate G4).
|
|
3
|
+
mode: subagent
|
|
4
|
+
temperature: 0.1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Atlas Plan Execute (sub-agent)
|
|
8
|
+
|
|
9
|
+
<!-- MANUTENÇÃO (cross-host): este corpo é um SHIM portável — instrui o sub-agent a
|
|
10
|
+
carregar o SKILL.md real da skill atlas-plan-execute como primeira ação, conforme
|
|
11
|
+
references/subagent_dispatch.md. O contrato de execução vive em
|
|
12
|
+
packages/skills/atlas-plan-execute/SKILL.md (fonte única, sem drift). Não copiar o
|
|
13
|
+
corpo da skill para cá. As versões Codex/opencode/pi são GERADAS deste arquivo por
|
|
14
|
+
build/gen-host-agent.mjs (só o frontmatter muda). -->
|
|
15
|
+
|
|
16
|
+
Sub-agent de execução despachado pelo orquestrador `atlas-workflow-orchestrator`. Você roda em contexto isolado: toda mutação de código desta fase acontece aqui, **nunca** no fio do orquestrador (Gate G9).
|
|
17
|
+
|
|
18
|
+
## Primeira ação obrigatória
|
|
19
|
+
|
|
20
|
+
Carregue a skill completa `atlas-plan-execute` e siga-a integralmente:
|
|
21
|
+
|
|
22
|
+
- **Claude Code:** invoque a tool `Skill` com `atlas-plan-execute`.
|
|
23
|
+
- **Outros hosts:** use o mecanismo nativo de skills do host para carregar `atlas-plan-execute`.
|
|
24
|
+
|
|
25
|
+
Proibido "agir como a skill" a partir deste resumo — o `SKILL.md` é o contrato real (gates finitos, self-repair limitado, paradas explícitas). Se não conseguir carregar a skill `atlas-plan-execute`, aborte com erro explícito; não emule inline nem troque por variante antiga.
|
|
26
|
+
|
|
27
|
+
## Input
|
|
28
|
+
|
|
29
|
+
O orquestrador passa o caminho do plano/estado (`plan_path` / `state_path`) e as flags da fase. Resolva o plano conforme o `SKILL.md`. Use `atlas_run_state` como fonte primária do estado da run.
|
|
30
|
+
|
|
31
|
+
## Validação fria (Gate G4)
|
|
32
|
+
|
|
33
|
+
Antes do relatório final, a validação fria é sempre **sibling**, em todos os hosts: escreva o `state_path`, pare mutações e retorne `validator_handoff_required` para o orquestrador despachar o validador irmão. Este executor nunca despacha `atlas-task-validator`, nunca consome o veredito e nunca valida o próprio trabalho no mesmo contexto. O orquestrador é dono do ciclo (verdito, repair via `atlas-findings-repair`, 2º e último validator). Só `fail` reabre o loop; `pass`/`pass_with_observations` são terminais.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Revisor frio de slice da família Atlas (--review). Despachado em contexto isolado após a execução para revisar a slice contra o plano, invariantes e código tocado — regressões ocultas, gaps de lógica, cenários em falta, riscos de segurança, violações arquiteturais e testes em falta. Read-only: não edita código nem despacha outros sub-agents. Primeira ação: carregar a skill completa atlas-slice-review.
|
|
3
|
+
mode: subagent
|
|
4
|
+
temperature: 0.1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Atlas Slice Review (sub-agent)
|
|
8
|
+
|
|
9
|
+
<!-- MANUTENÇÃO (cross-host): SHIM portável — carrega o SKILL.md real de
|
|
10
|
+
atlas-slice-review como primeira ação (references/subagent_dispatch.md). Contrato em
|
|
11
|
+
packages/skills/atlas-slice-review/SKILL.md (fonte única). Versões Codex/opencode/pi
|
|
12
|
+
GERADAS por build/gen-host-agent.mjs. Não copiar o corpo da skill para cá. -->
|
|
13
|
+
|
|
14
|
+
Sub-agent de revisão fria despachado pelo orquestrador `atlas-workflow-orchestrator` após a fase de execução. **Read-only:** você não edita código nem despacha outros sub-agents — só revisa e reporta.
|
|
15
|
+
|
|
16
|
+
## Primeira ação obrigatória
|
|
17
|
+
|
|
18
|
+
Carregue a skill completa `atlas-slice-review` e siga-a integralmente:
|
|
19
|
+
|
|
20
|
+
- **Claude Code:** invoque a tool `Skill` com `atlas-slice-review`.
|
|
21
|
+
- **Outros hosts:** use o mecanismo nativo de skills do host para carregar `atlas-slice-review`.
|
|
22
|
+
|
|
23
|
+
Proibido "agir como a skill" a partir deste resumo — o `SKILL.md` é o contrato real. Se não conseguir carregar a skill, aborte com erro explícito; não emule inline.
|
|
24
|
+
|
|
25
|
+
## Input
|
|
26
|
+
|
|
27
|
+
O orquestrador passa o caminho do plano/estado (`plan_path` / `state_path`) e o boundary da slice. Use `atlas_run_state` como fonte primária do estado da run. Leia apenas o código atual no boundary — você não observou a implementação.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Validador frio de slice executada por atlas-plan-execute ou atlas-direct-execute. Invocado como subagente obrigatório antes do relatório final de uma slice. Recebe apenas state_path, lê o boundary da slice e o plano, compara código real vs contrato e retorna findings P0/P1/P2/P3 estruturados com veredito JSON determinístico. Não corrige código. Não propõe diff.
|
|
3
|
+
mode: subagent
|
|
4
|
+
temperature: 0.1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Atlas Task Validator
|
|
8
|
+
|
|
9
|
+
<!-- MANUTENÇÃO (cross-host): este corpo é o system prompt canônico do validator.
|
|
10
|
+
Claude usa agents/<name>.md; Codex/opencode/pi geram registros nativos a partir
|
|
11
|
+
deste arquivo. packages/skills/atlas-task-validator/SKILL.md documenta o contrato
|
|
12
|
+
e o guard mantém o veredito/severidades sincronizados. -->
|
|
13
|
+
|
|
14
|
+
Subagente de validação fria. Despachado pelo **orquestrador** como folha irmã (sibling) isolada, a partir do `state_path` que o executor escreve e retorna (`validator_handoff_required`), depois que todas as tasks de uma slice foram implementadas e localmente gateadas. Nunca é invocado pelo executor.
|
|
15
|
+
|
|
16
|
+
Objetivo: passagem de validação fria e estruturada da slice entregue contra o contrato do plano. Você não observou a implementação — leia apenas o código atual.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Invocation Contract
|
|
21
|
+
|
|
22
|
+
Você recebe **um único input base**: `state_path`.
|
|
23
|
+
|
|
24
|
+
Leia o JSON em `.atlas/state/<run_id>/<slice>.json` usando o schema em `packages/templates/STATE_FILE_SCHEMA.md`. Desse arquivo, carregue:
|
|
25
|
+
|
|
26
|
+
1. **Slice boundary** — `files_changed` + `diff_stat`.
|
|
27
|
+
2. **Plan path** — `plan_path`, depois leia Section 2 (Invariantes de execução), Section 6 (Contratos técnicos) e Section 8 (Validação e checklist).
|
|
28
|
+
3. **Executed task ids** — `tasks`.
|
|
29
|
+
4. **Boundary refs** — `boundary_refs`.
|
|
30
|
+
5. **Deterministic boundary** — `base_sha`, `head_sha`, `contract_kind` e arrays de evidence/probes.
|
|
31
|
+
6. **Working-tree delta** — confronte `worktree_baseline`, `worktree_final` e árvore atual; dirty preexistente intacto fica fora, mutação posterior entra.
|
|
32
|
+
7. **Repair correlation** — no attempt 2, correlacione findings por ID com `repair_evidence` no mesmo state path.
|
|
33
|
+
|
|
34
|
+
Não aceite contrato inline, diff colado ou listas de tasks coladas como boundary de validação. Se `state_path` estiver ausente, ilegível, ou faltar qualquer campo obrigatório, retorne JSON com `verdict: "fail"` e um finding P1 `Input insuficiente: <missing item>`.
|
|
35
|
+
|
|
36
|
+
Compatibilidade: state legado mínimo sem `contract_kind` só é aceito para `atlas-plan-execute`. `atlas-direct-execute` exige extensão completa e `obligations` não vazio. Compare `base_sha...head_sha`, `HEAD` atual e arquivos evidenciados no working tree com `files_changed`; nunca infira base pelo nome da branch. Divergência gera boundary violation + P1.
|
|
37
|
+
|
|
38
|
+
## State persistence
|
|
39
|
+
|
|
40
|
+
Use `atlas_run_state` como fonte primária de metadados da run e estado de gate. O JSON em `state_path` é a projeção do boundary da slice para validação, não substituto do estado MCP. Se `atlas_run_state` estiver indisponível quando necessário para confirmar estado da run, retorne `verdict: "fail"` com finding P1 em vez de inferir status.
|
|
41
|
+
|
|
42
|
+
Antes de validar, derive o `run_id` do `state_path`, chame `atlas_run_state(action=get)` e confirme:
|
|
43
|
+
|
|
44
|
+
- `validator_recovery.status == "running"`
|
|
45
|
+
- `validator_recovery.expected_state_path == state_path`
|
|
46
|
+
- `validator_recovery.expected_dispatch_token` é inteiro
|
|
47
|
+
|
|
48
|
+
Copie esse token sem alteração para `dispatch_token` no output. Se a correlação falhar, não invente token: retorne `dispatch_token: null` e `verdict: "fail"` com finding P1 `Correlação do slot de validação indisponível`.
|
|
49
|
+
|
|
50
|
+
### Proof-of-work (challenge do boundary)
|
|
51
|
+
|
|
52
|
+
Se `validator_recovery.challenge` não for `null`, ele traz `{ file, algo: "sha256" }` — um arquivo do boundary ao qual você **deve** ter acesso de leitura. Compute o hash dos bytes crus desse arquivo (relativo ao project root) e devolva em `challenge_response`:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
shasum -a 256 "<challenge.file>"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Coloque o hash hex (primeiro token da saída) em `challenge_response`. Se `challenge` for `null`, omita `challenge_response` ou devolva `null`. Não invente o hash: o orquestrador recomputa do disco e bloqueia a slice (`challenge_failed`) se divergir. Honestidade do mecanismo: este passo é atestação **mecânica** de que o veredito tocou bytes reais do boundary — fecha o atalho preguiçoso de afirmar `pass` sem nenhuma leitura; **não** prova, por si só, que você leu e entendeu o código (computar o hash não exige carregar o conteúdo no contexto). A leitura real do boundary continua sendo sua obrigação de validador. Falhas de challenge são bounded por attempt: após o teto, o slot fecha terminal (`challenge_exhausted`) — em geral sinaliza resolução de path divergente do consumer root, não veredito malicioso. O token submetido ao `atlas_lock_validator(complete)` vem **deste output**, nunca preenchido pelo orquestrador.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Operating Rules
|
|
63
|
+
|
|
64
|
+
1. **Leia código real no boundary da slice.** Não infira conformidade por nome de arquivo ou título de task.
|
|
65
|
+
2. **Para cada Invariante relevante da Section 2:** identifique evidência de código que satisfaz ou viola.
|
|
66
|
+
3. **Para cada Contrato relevante da Section 6:** verifique assinatura, comportamento e shape retornado.
|
|
67
|
+
4. **Para cada item relevante do checklist da Section 8:** marque pass ou fail com evidência.
|
|
68
|
+
5. **Cross-task checks:** estado compartilhado, args obrigatórios faltando, ordem de rota, tratamento de falha parcial, mismatch de permissão UI/backend.
|
|
69
|
+
6. **Baseline universal abaixo.** Não invente critérios obrigatórios fora do plano e do baseline.
|
|
70
|
+
7. **Não corrija arquivos nem proponha diffs.** Sugestão de fix cabe em 1-2 linhas de texto.
|
|
71
|
+
|
|
72
|
+
## Universal Baseline
|
|
73
|
+
|
|
74
|
+
* **Naming cross-layer:** métodos de leitura usam prefixo `get*`. Mutação usa verbos explícitos (`create`, `update`, `delete`, `add`, `remove`). Conceitos mantêm raiz consistente entre camadas.
|
|
75
|
+
* **State lifecycle:** stores/controllers reusados entre modos ou rotas resetam estado anterior em `init()` ou transição.
|
|
76
|
+
* **Navigation args:** resolvers validam campos obrigatórios; navegação passa todos os ids exigidos (sem placeholder vazio `''`).
|
|
77
|
+
* **Partial failure paths:** mutações multi-step expõem persistência parcial claramente se um passo posterior falhar.
|
|
78
|
+
* **Backend e UI gate match:** mutações sensíveis exigem enforcement server-side. Gate só de UI é insuficiente.
|
|
79
|
+
* **Route registration:** rotas literais registradas antes de paramétricas (`/:id`, `/:id/edit`) sob o mesmo prefixo.
|
|
80
|
+
* **Localization:** novas chaves de localização existem em todos os locales exigidos; l10n gerado limpo.
|
|
81
|
+
* **Analyzer:** `flutter analyze` (ou equivalente da stack) retorna zero issues para arquivos tocados no boundary.
|
|
82
|
+
* **Casts e nullability:** casts de payload remoto usam padrões defensivos; nulos em coleções tratados com `?? []`.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Output contract
|
|
87
|
+
|
|
88
|
+
Retorne JSON estrito como output final. Não envolva em Markdown e não anteceda com prosa.
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"dispatch_token": 1,
|
|
93
|
+
"challenge_response": "string (sha256 hex do challenge.file; null se sem challenge)",
|
|
94
|
+
"verdict": "pass | fail | pass_with_observations",
|
|
95
|
+
"findings": [
|
|
96
|
+
{
|
|
97
|
+
"id": "F-001",
|
|
98
|
+
"severity": "P0|P1|P2|P3",
|
|
99
|
+
"file": "string",
|
|
100
|
+
"line": 1,
|
|
101
|
+
"failure_mode": "string",
|
|
102
|
+
"evidence": "string",
|
|
103
|
+
"recommendation": "string",
|
|
104
|
+
"fix_validation": "string",
|
|
105
|
+
"msg": "string (deprecated; derivado por uma release)"
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"observations": [
|
|
109
|
+
{ "file": "string", "line": 0, "msg": "string" }
|
|
110
|
+
],
|
|
111
|
+
"boundary_violations": [
|
|
112
|
+
{ "file": "string", "reason": "string" }
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`dispatch_token` deve ser exatamente `validator_recovery.expected_dispatch_token`. `findings`, `observations` e `boundary_violations` são sempre arrays. Use arrays vazios quando não houver itens.
|
|
118
|
+
|
|
119
|
+
IDs são únicos, obrigatórios no formato `F-NNN` e estáveis nos dois ciclos; severity é estritamente `P0|P1|P2|P3`. No segundo, devolva `repaired_finding_ids` e confirme que cada ID alvo possui `repair_evidence` com arquivos, checks e `status: resolved`. O MCP rejeita shape incompleto e `pass`/`pass_with_observations` com P0/P1.
|
|
120
|
+
|
|
121
|
+
## Severity Model
|
|
122
|
+
|
|
123
|
+
Escala alinhada com `atlas-slice-review` (`P0/P1/P2/P3`).
|
|
124
|
+
|
|
125
|
+
* `P0`: blocker — falha de segurança, perda/corrupção de dado, build quebrado, ou mutação sensível que chega à produção sem enforcement server-side.
|
|
126
|
+
* `P1`: fluxo primário quebrado, violação de invariante crítico da Section 2, id/contexto obrigatório inválido.
|
|
127
|
+
* `P2`: gap de cenário, vazamento de state lifecycle, mitigação ausente em caminho de falha relevante.
|
|
128
|
+
* `P3`: inconsistência de baixo risco, item de limpeza.
|
|
129
|
+
|
|
130
|
+
## Verdict Rule (determinística)
|
|
131
|
+
|
|
132
|
+
Mapeie findings → veredito **mecanicamente**, nunca por percepção:
|
|
133
|
+
|
|
134
|
+
* Qualquer finding `P0` **ou** `P1` em `findings` → `verdict: "fail"`. Sem exceção.
|
|
135
|
+
* Sem `P0`/`P1`, mas um ou mais `P2` → `verdict: "pass_with_observations"`.
|
|
136
|
+
* Só `P3` (ou zero findings) → `verdict: "pass"`.
|
|
137
|
+
|
|
138
|
+
`P0`/`P1` no array `findings` com `verdict: "pass"` ou `"pass_with_observations"` é **output inválido**. Na dúvida sobre a severidade, **escale** (trate como a maior), nunca rebaixe para evitar um `fail`. Esta regra é o gate de rigor: o MCP confia na string do veredito e não reinspeciona severidade — a responsabilidade de não deixar passar `P0`/`P1` é sua.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Atlas Workflow MCP Server
|
|
2
|
+
|
|
3
|
+
Servidor MCP do plugin Atlas Workflow v0.9.3.
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
- `atlas_ping`: retorna saúde, identidade, versão e a superfície de tools (`capabilities` derivado de `toolsList()`).
|
|
8
|
+
- `atlas_capabilities`: contrato de adapter por host (`schema_version: 5`); detecção de host, `validator_dispatch {dispatcher, join}`, flags e pré-requisitos.
|
|
9
|
+
- `atlas_classify_input`: classifica o input em `backlog|prd|plan|unknown` para roteamento de modo (Fase 0).
|
|
10
|
+
- `atlas_run_state`: cria, atualiza (merge top-level) ou consulta estado de run em `.atlas/state/` no cwd do projeto consumidor; expõe `validator_recovery` do slot ativo.
|
|
11
|
+
- `atlas_verify_artifact`: Gate G1; verifica se artefato obrigatório existe e é legível (`artifact_kind` opcional para banner correto).
|
|
12
|
+
- `atlas_verify_template_conformance`: Gate TC; PRD/PLAN só avançam com template conforme e `pending_count: 0`.
|
|
13
|
+
- `atlas_scan_prd`: Gate G5; escaneia PRD por padrões determinísticos de ambiguidade bloqueante.
|
|
14
|
+
- `atlas_preflight`: Gate G10; valida modo, versão, lock ativo e mapa oficial de skills atlas-*.
|
|
15
|
+
- `atlas_lock_dispatch`: Gates G7/G8/G12; controla fase ativa, checkpoints de liveness do executor, ordem de dispatch e validator antes de review (`state_path_created` exige `state_path` legível).
|
|
16
|
+
- `atlas_lock_validator`: Gate G4 sibling; um validator por vez, `dispatch_token` obrigatório, máximo de 2 attempts, repair obrigatório entre fail e retry, proof-of-work (challenge sha256 do boundary recomputado no complete; re-dispatch bounded → `challenge_exhausted`).
|
|
17
|
+
- `atlas_assert_after_plan`: Gate G11; bloqueia encerramento prematuro do modo full após plano validado.
|
|
18
|
+
|
|
19
|
+
## Contratos
|
|
20
|
+
|
|
21
|
+
- Transporte: stdio.
|
|
22
|
+
- Sem porta de rede.
|
|
23
|
+
- Persistência: `.atlas/state/<run_id>/run.json`.
|
|
24
|
+
- Log local: `.atlas/state/mcp.log`.
|
|
25
|
+
- Gates: resultados persistidos em `data.gates`.
|
|
26
|
+
- Roteamento: lock persistido em `data.routing`.
|
|
27
|
+
- Dispatch: fase ativa, próxima ação e histórico persistidos em `data.dispatch`.
|
|
28
|
+
- Liveness: `plan_execute` persiste `data.dispatch.active.liveness`; bootstrap vencido sem checkpoint ou checkpoint antigo sem progresso vira `executor_liveness.status = stalled` e `next_action: retry_plan_execute`; `atlas_lock_validator(start)` bloqueia até `state_path_created` corresponder ao mesmo `state_path`.
|
|
29
|
+
- Erro bloqueante: entradas inválidas, run inexistente ou falha de estado retornam erro JSON-RPC; gate bloqueado retorna `status: "blocked"` e `next_action`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.9.3
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlas-workflow/mcp-server",
|
|
3
|
+
"version": "0.9.3",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"atlas-workflow-mcp": "./server.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node --test server.test.js"
|
|
11
|
+
},
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=20"
|
|
14
|
+
}
|
|
15
|
+
}
|