@orkastery/cli 0.6.0 → 0.6.2

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.
Files changed (118) hide show
  1. package/adapters/claude-code/agents/ork-check.md +1 -1
  2. package/adapters/claude-code/agents/ork-go.md +1 -1
  3. package/adapters/claude-code/agents/ork-goal.md +1 -1
  4. package/adapters/claude-code/agents/ork-master.md +1 -1
  5. package/adapters/claude-code/agents/ork-plan.md +1 -1
  6. package/adapters/claude-code/agents/ork-ship.md +1 -1
  7. package/adapters/claude-code/commands/ork.md +1 -1
  8. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +2 -0
  9. package/adapters/codex/skills/ork/SKILL.md +1 -1
  10. package/adapters/openclaw/openclaw.plugin.json +1 -1
  11. package/adapters/openclaw/package.json +1 -1
  12. package/assets/adapters-en/claude-code/agents/ork-check.md +1 -1
  13. package/assets/adapters-en/claude-code/agents/ork-go.md +1 -1
  14. package/assets/adapters-en/claude-code/agents/ork-goal.md +1 -1
  15. package/assets/adapters-en/claude-code/agents/ork-master.md +1 -1
  16. package/assets/adapters-en/claude-code/agents/ork-plan.md +1 -1
  17. package/assets/adapters-en/claude-code/agents/ork-ship.md +1 -1
  18. package/assets/adapters-en/claude-code/commands/ork.md +1 -1
  19. package/assets/adapters-en/codex/skills/ork/SKILL.md +1 -1
  20. package/assets/orkmind_fixture.py +4 -1
  21. package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +1 -1
  22. package/assets/skills-en/phases/check-quality/SKILL.md +1 -1
  23. package/assets/skills-en/phases/go-implementation/SKILL.md +1 -1
  24. package/dist/adapters/claude-bg.js +9 -7
  25. package/dist/adapters/grok-events.js +227 -0
  26. package/dist/adapters/grok-mcp-servidor.js +622 -0
  27. package/dist/adapters/grok-mcp.js +178 -0
  28. package/dist/adapters/grok.js +686 -0
  29. package/dist/agendador-cpu.js +92 -0
  30. package/dist/branch-de-estado.js +7 -2
  31. package/dist/changelog-check.js +217 -0
  32. package/dist/check-agil.js +289 -25
  33. package/dist/check-paralelo.js +73 -18
  34. package/dist/ci.js +3 -2
  35. package/dist/claim-lint.js +29 -0
  36. package/dist/claims.js +4 -0
  37. package/dist/conducao.js +5 -0
  38. package/dist/docs.js +16 -16
  39. package/dist/doctor-forja.js +1 -3
  40. package/dist/doctor.js +1 -1
  41. package/dist/entrega-pr.js +10 -10
  42. package/dist/fabrica-estado.js +20 -11
  43. package/dist/fila-pesada.js +121 -11
  44. package/dist/hitl-classificacao.js +1 -0
  45. package/dist/horario.js +4 -1
  46. package/dist/index.js +63 -35
  47. package/dist/integracoes-locais.js +2 -0
  48. package/dist/intelligence-graph-cli.js +27 -9
  49. package/dist/locale-accounts.js +11 -3
  50. package/dist/locale-ajuda.js +10 -6
  51. package/dist/locale-claims.js +16 -2
  52. package/dist/locale-forja.js +2 -4
  53. package/dist/locale-grafo.js +56 -1
  54. package/dist/locale-maestro.js +38 -0
  55. package/dist/locale-network.js +8 -6
  56. package/dist/locale-onboarding.js +14 -0
  57. package/dist/locale-operacao-restante.js +2 -2
  58. package/dist/locale-preflight.js +80 -0
  59. package/dist/locale-projetos.js +6 -0
  60. package/dist/locale-prompts.js +8 -8
  61. package/dist/locale-pulse.js +4 -0
  62. package/dist/locale-retry.js +56 -2
  63. package/dist/locale-security-scan.js +35 -1
  64. package/dist/locale-ship.js +10 -2
  65. package/dist/locale-verify.js +15 -0
  66. package/dist/locale.js +24 -7
  67. package/dist/maestro-cli.js +12 -17
  68. package/dist/manifest.js +6 -1
  69. package/dist/mcp-install.js +24 -13
  70. package/dist/mcp-server.js +62 -33
  71. package/dist/mcp-verify-async.js +353 -0
  72. package/dist/mcp-verify-worker.js +17 -0
  73. package/dist/mcp-verify.js +10 -1
  74. package/dist/merge-da-entrega.js +85 -0
  75. package/dist/network-roadmap.js +18 -14
  76. package/dist/noctum-aceite.js +154 -14
  77. package/dist/noctum-cli.js +69 -12
  78. package/dist/noctum-entrega.js +55 -7
  79. package/dist/noctum-envelope.js +1 -1
  80. package/dist/noctum-execucao.js +5 -1
  81. package/dist/noctum-fechamento.js +18 -7
  82. package/dist/noctum-fila.js +6 -1
  83. package/dist/noctum-guarda.js +81 -4
  84. package/dist/noctum-maquinas.js +5 -1
  85. package/dist/noctum-modo.js +35 -7
  86. package/dist/noctum-reconciliacao.js +4 -1
  87. package/dist/noctum-rede.js +102 -0
  88. package/dist/noctum-relatorio.js +44 -10
  89. package/dist/noctum-retomada-rede.js +71 -0
  90. package/dist/noctum-vigia.js +49 -9
  91. package/dist/parado-no-condutor.js +14 -15
  92. package/dist/pedido-conducao.js +51 -0
  93. package/dist/phase.js +43 -15
  94. package/dist/postura-local.js +7 -3
  95. package/dist/preflight.js +27 -27
  96. package/dist/prompts.js +4 -2
  97. package/dist/pulse.js +4 -2
  98. package/dist/ratelimit.js +1 -0
  99. package/dist/rede.js +24 -12
  100. package/dist/retry.js +115 -10
  101. package/dist/runtime-context.js +165 -45
  102. package/dist/runtime-escada.js +7 -1
  103. package/dist/runtime-profiles.js +27 -17
  104. package/dist/runtimes.js +42 -5
  105. package/dist/security-scan/agil.js +18 -7
  106. package/dist/security-scan/cli.js +2 -2
  107. package/dist/security-scan/executor.js +8 -0
  108. package/dist/security-scan/report.js +1 -1
  109. package/dist/session-watcher-grok.js +425 -0
  110. package/dist/session-watcher.js +52 -11
  111. package/dist/sessoes-contas.js +33 -5
  112. package/dist/setup.js +11 -11
  113. package/dist/varredura-acoes.js +8 -15
  114. package/dist/verify.js +191 -43
  115. package/package.json +2 -2
  116. package/skills/core/orkastery-bootstrap/SKILL.md +1 -1
  117. package/skills/phases/check-quality/SKILL.md +1 -1
  118. package/skills/phases/go-implementation/SKILL.md +1 -1
@@ -82,6 +82,14 @@ exports.VERIFY_PT_BR = {
82
82
  semVeredito: (nomes) => `Sem veredito por tempo (nao e reprovacao: prazo estourado ou relogio sob steal): ${nomes}`,
83
83
  // Classificacao e veredito
84
84
  classificacao: (regressoes, preExistentes, semBaseline) => `Classificacao: ${regressoes} regressao(oes), ${preExistentes} pre-existente(s), ${semBaseline} falha(s) sem baseline`,
85
+ comparacaoPorTeste: (comando, regressoes, preExistentes, corrigidos) => `Comparacao teste a teste (${comando}): ${regressoes} regressao(oes), ${preExistentes} pre-existente(s), ` +
86
+ `${corrigidos} corrigido(s)`,
87
+ testeRegressao: (nome) => ` regressao ${nome}`,
88
+ testePreExistente: (nome) => ` pre-existente ${nome}`,
89
+ testeCorrigido: (nome) => ` corrigido ${nome}`,
90
+ comparacaoPorComando: (comando, classificacao, motivo) => `Comparacao somente por comando (${comando}): ${classificacao}; ${motivo === 'baseline-sem-nomes'
91
+ ? 'a baseline nao guardou nomes de testes' : 'a rodada atual nao informou nomes de testes'}. ` +
92
+ 'Nenhuma contagem de regressoes por teste foi calculada.',
85
93
  regressao: (nome, comando) => ` regressao ${nome}: ${comando}`,
86
94
  preExistente: (nome, comando) => ` pre-existente ${nome}: ${comando}`,
87
95
  falhaSemBaseline: (nome, comando) => ` sem baseline ${nome}: ${comando}`,
@@ -171,6 +179,13 @@ exports.VERIFY_EN = {
171
179
  falhou: (code) => `FAILED (exit ${code})`,
172
180
  semVeredito: (nomes) => `No verdict for lack of time (not a failure: deadline exceeded or clock under steal): ${nomes}`,
173
181
  classificacao: (regressoes, preExistentes, semBaseline) => `Classification: ${regressoes} regression(s), ${preExistentes} pre-existing, ${semBaseline} failure(s) without a baseline`,
182
+ comparacaoPorTeste: (comando, regressoes, preExistentes, corrigidos) => `Test-by-test comparison (${comando}): ${regressoes} regression(s), ${preExistentes} pre-existing, ${corrigidos} fixed`,
183
+ testeRegressao: (nome) => ` regression ${nome}`,
184
+ testePreExistente: (nome) => ` pre-existing ${nome}`,
185
+ testeCorrigido: (nome) => ` fixed ${nome}`,
186
+ comparacaoPorComando: (comando, classificacao, motivo) => `Command-only comparison (${comando}): ${classificacao === 'regressao' ? 'regression' : classificacao === 'pre-existente'
187
+ ? 'pre-existing' : 'fixed'}; ${motivo === 'baseline-sem-nomes' ? 'the baseline did not store test names'
188
+ : 'the current run did not report test names'}. No per-test regression count was calculated.`,
174
189
  regressao: (nome, comando) => ` regression ${nome}: ${comando}`,
175
190
  preExistente: (nome, comando) => ` pre-existing ${nome}: ${comando}`,
176
191
  falhaSemBaseline: (nome, comando) => ` no baseline ${nome}: ${comando}`,
package/dist/locale.js CHANGED
@@ -108,22 +108,25 @@ const locale_operacao_restante_1 = require("./locale-operacao-restante");
108
108
  const locale_conducao_1 = require("./locale-conducao");
109
109
  const locale_grafo_1 = require("./locale-grafo");
110
110
  const locale_audit_1 = require("./locale-audit");
111
+ const locale_preflight_1 = require("./locale-preflight");
112
+ const locale_maestro_1 = require("./locale-maestro");
111
113
  exports.LOCALE_PADRAO = 'pt-BR';
112
114
  /**
113
115
  * Comandos cujo texto ja sai pelo catalogo, por `comando` ou por `comando subcomando`; `comando ?` e o
114
116
  * subcomando desconhecido (o erro de uso e do proprio comando). Os demais seguem em pt-BR. Ficam de
115
- * fora por decisao (D2 da F2a): `doctor --modo`, `thread new --from-finding`, `onboarding sync` e
116
- * `experiencia uninstall`. A F2b (G3) acrescenta `verify` (com `--baseline`),
117
+ * fora por decisao (D2 da F2a): `thread new --from-finding`. A F3e acrescenta `doctor --modo`,
118
+ * `onboarding sync` e `experiencia uninstall`. A F2b (G3) acrescenta `verify` (com `--baseline`),
117
119
  * `ship`, `ship registrar-pr`, `retry plan`, `retry run`, `master` (o indice), `master aceitar-omissao` e
118
120
  * `master pedir`, `pulse` (sem `responder` nem `cadencia`) e `roadmap status`. A F3a (D5) acrescenta `docs init`, e a
119
121
  * F3b (D1), o resto da lista do dono; a F3c completa `decisao registrar` e `network roadmap`. O conhecimento escrito
120
122
  * (RM-026 K7, fatia 2) nasce coberto: `conhecimento listar|mostrar|colecoes|verificar` e o uso errado dele.
121
123
  */
122
124
  exports.COMANDOS_COM_LOCALE = ['doctor', 'init', 'onboarding show', 'onboarding set', 'onboarding reset',
123
- 'onboarding ?', 'experiencia show', 'experiencia ?', 'thread new', 'thread status', 'thread ?',
125
+ 'onboarding sync', 'onboarding ?', 'experiencia show', 'experiencia uninstall', 'experiencia ?', 'thread new', 'thread status', 'thread ?',
124
126
  'phase list', 'phase run', 'phase ?', 'verify', 'ship', 'ship registrar-pr', 'retry plan', 'retry run',
125
127
  'retry policy', 'retry parse', 'retry list', 'retry resume', 'retry cancel', 'retry ?',
126
- 'master', 'master <thread>', 'master aceitar-omissao', 'master pedir', 'master classes', 'master batch',
128
+ 'master', 'master <thread>', 'master aceitar-omissao', 'master pedir', 'master audit', 'master digest', 'master migrar',
129
+ 'master classes', 'master ratificar', 'master batch', 'master propor',
127
130
  'pulse', 'roadmap status', 'docs init',
128
131
  // F3b (D1): o resto do CLI, na ordem do pedido.
129
132
  'thread list', 'thread close', 'thread entrega', 'worktree ensure', 'worktree sync', 'worktree audit', 'worktree release', 'worktree ?',
@@ -151,7 +154,7 @@ exports.COMANDOS_COM_LOCALE = ['doctor', 'init', 'onboarding show', 'onboarding
151
154
  'orquestracao status', 'orquestracao ?', 'monitor', 'licoes', 'demo',
152
155
  'fabrica list', 'fabrica publicar', 'fabrica entrar', 'fabrica sair', 'fabrica batida', 'fabrica ?', 'eval',
153
156
  'memory status', 'memory inventory', 'memory migrate', 'memory sync', 'memory search', 'memory index', 'memory ?',
154
- 'mcp install', 'conducao status', 'conducao assumir', 'conducao atualizar', 'conducao autorizar',
157
+ 'mcp install', 'mcp serve', 'mcp ?', 'brain', 'activation', 'conducao status', 'conducao assumir', 'conducao atualizar', 'conducao autorizar',
155
158
  'conducao autorizacao', 'conducao batida', 'conducao sentinela', 'conducao ?', 'grafo',
156
159
  'audit packs', 'audit pack', 'audit lint', 'audit run', 'audit list', 'audit show', 'audit prompt',
157
160
  'audit ingest', 'audit finding', 'audit achado', 'audit verify', 'audit report', 'audit relatorio',
@@ -226,8 +229,6 @@ function chaveDoMaster(bruto, opcoes) {
226
229
  function cobreLocale(posicionais, opcoes) {
227
230
  if (opcoes.json !== undefined)
228
231
  return false;
229
- if (posicionais[0] === 'doctor' && opcoes.modo !== undefined)
230
- return false;
231
232
  return exports.COMANDOS_COM_LOCALE.includes(chaveDoLocale(posicionais, opcoes));
232
233
  }
233
234
  /** `en_US.UTF-8`, `en-GB`, `en` viram `en`; `pt_BR.UTF-8`, `pt` viram pt-BR; o resto, undefined. */
@@ -293,7 +294,14 @@ const PT_BR = {
293
294
  subcomandoDesconhecido: (comando, sub) => `subcomando desconhecido: ${comando} ${sub}`,
294
295
  /** `exigirManifesto` fora de um projeto: o primeiro erro de quem chega (D14). */
295
296
  manifestoNaoEncontrado: (nome, dir) => `manifesto ${nome} nao encontrado a partir de ${dir}. Rode: ork init`,
297
+ receiptVerifiersUso: 'uso: ork receipt-verifiers --json',
298
+ activationUso: 'uso: ork activation plan|status|enable|disable',
299
+ masterDigestUso: 'uso: ork master digest <enviar|preview|responder>',
300
+ masterRatificarUso: 'resposta deve ser ratificar <thread> <assinatura> <classe>',
301
+ masterSelecaoUso: 'seleção deve ser thread:assinatura',
296
302
  },
303
+ preflight: locale_preflight_1.PREFLIGHT_PT_BR,
304
+ maestro: locale_maestro_1.MAESTRO_PT_BR,
297
305
  horario: {
298
306
  brasilia: 'horário de Brasília',
299
307
  legendaBrasilia: 'Horários de Brasília.',
@@ -307,6 +315,7 @@ const PT_BR = {
307
315
  },
308
316
  doctor: {
309
317
  titulo: 'ork doctor: o que vale nesta maquina agora',
318
+ modoUso: (modos) => `uso: ork doctor --modo ${modos}`,
310
319
  correcao: 'correcao',
311
320
  bloqueado: (falhas, avisos) => `Veredito: BLOQUEADO (${falhas} fail, ${avisos} warn). Corrija os itens acima antes de despachar fase.`,
312
321
  pronto: (avisos) => `Veredito: PRONTO (${avisos} warn). Despacho de fase liberado por \`ork phase run\`.`,
@@ -731,7 +740,14 @@ const EN = {
731
740
  erro: (mensagem) => `error: ${mensagem}`,
732
741
  subcomandoDesconhecido: (comando, sub) => sub === undefined ? `missing subcommand: ${comando}` : `unknown subcommand: ${comando} ${sub}`,
733
742
  manifestoNaoEncontrado: (nome, dir) => `\`${nome}\` not found in ${dir} or any parent directory; run \`ork init\` first.`,
743
+ receiptVerifiersUso: 'usage: ork receipt-verifiers --json',
744
+ activationUso: 'usage: ork activation plan|status|enable|disable',
745
+ masterDigestUso: 'usage: ork master digest <enviar|preview|responder>',
746
+ masterRatificarUso: 'the response must be ratificar <thread> <signature> <class>',
747
+ masterSelecaoUso: 'the selection must be thread:signature',
734
748
  },
749
+ preflight: locale_preflight_1.PREFLIGHT_EN,
750
+ maestro: locale_maestro_1.MAESTRO_EN,
735
751
  horario: {
736
752
  brasilia: 'Brasília time',
737
753
  legendaBrasilia: 'Times in Brasília time.',
@@ -744,6 +760,7 @@ const EN = {
744
760
  },
745
761
  doctor: {
746
762
  titulo: 'ork doctor: what holds on this machine now',
763
+ modoUso: (modes) => `usage: ork doctor --modo ${modes}`,
747
764
  correcao: 'fix',
748
765
  bloqueado: (falhas, avisos) => `Verdict: BLOCKED (${falhas} fail, ${avisos} warn). Fix the items above before dispatching a phase.`,
749
766
  pronto: (avisos) => `Verdict: READY (${avisos} warn). Phase dispatch allowed through \`ork phase run\`.`,
@@ -10,6 +10,7 @@ const maestro_sources_1 = require("./maestro-sources");
10
10
  const maestro_actions_1 = require("./maestro-actions");
11
11
  const maestro_runtime_1 = require("./maestro-runtime");
12
12
  const horario_1 = require("./horario");
13
+ const locale_maestro_1 = require("./locale-maestro");
13
14
  function readMaestro(context, options) {
14
15
  const observations = options.native && options.threadId ? (0, maestro_runtime_1.nativeForThread)(context.root, options.threadId) : [];
15
16
  return (0, maestro_snapshot_1.maestroSnapshot)(context, { ...options, collect: ctx => {
@@ -31,31 +32,25 @@ function readMaestro(context, options) {
31
32
  return sources;
32
33
  } });
33
34
  }
34
- /** RM-052: de onde veio o projeto do panorama, na lingua do dono. */
35
- const ORIGEM_DO_PANORAMA = Object.freeze({
36
- installation: 'fixado na instalação', cwd: 'pelo diretório atual', worktree: 'pela worktree da thread',
37
- selection: 'pedido explicitamente (--projeto ou ORK_PROJETO)',
38
- });
39
- function maestroText(snapshot) {
35
+ function maestroText(snapshot, textos = locale_maestro_1.MAESTRO_PT_BR) {
40
36
  const p = snapshot.project;
41
- return [`${p.name} · panorama Maestro`,
37
+ return [textos.titulo(p.name),
42
38
  // I-35: o snapshot guarda ISO; o texto ao dono diz quando consultou, no fuso dele.
43
- `• Consulta: ${(0, horario_1.formatarDataHoraRotulada)(snapshot.observedAt, { agora: snapshot.observedAt })}`,
39
+ textos.consulta((0, horario_1.formatarDataHoraRotulada)(snapshot.observedAt, { agora: snapshot.observedAt })),
44
40
  // RM-052: qual cópia foi lida e o que o panorama não lê, antes de qualquer seção.
45
- `• Projeto consultado: ${p.name}${p.root ? ` · ${p.root}` : ''}${p.remote === undefined ? '' : ` · ${p.remote ?? 'sem remoto'}`} · ${ORIGEM_DO_PANORAMA[p.origin]}`,
46
- ...(snapshot.notConsulted?.length ? [`• Não lido: ${snapshot.notConsulted.join(' · ')}`] : []),
41
+ textos.projeto(p.name, p.root ?? '', p.remote === null ? textos.semRemoto : p.remote, textos.origem[p.origin]),
42
+ ...(snapshot.notConsulted?.length ? [textos.naoLido(snapshot.notConsulted.join(' · '))] : []),
47
43
  ...maestro_contract_1.SECTION_NAMES.map(name => {
48
44
  const s = snapshot.sections[name];
49
- return `• ${name}: ${s.state} · ${s.coverage.returned}/${s.coverage.total ?? '?'}${s.coverage.omitted ? ' · mais itens disponíveis' : ''}`;
45
+ return textos.secao(name, s.state, s.coverage.returned, s.coverage.total, !!s.coverage.omitted);
50
46
  }),
51
- ...snapshot.sections.threads.items.slice(0, 8).map(t => ` ${t.title}: ${t.facts.phase} · ${t.status}`),
52
- `• Recomendo: ${snapshot.conflicts.length ? 'reler as fontes em conflito' : snapshot.gaps.length ? 'conferir as lacunas antes de agir' : 'escolher uma thread para ver o detalhe'}.`,
53
- 'Use ork maestro --json para cobertura e ações; --thread ID consulta o detalhe nativo.',
47
+ ...snapshot.sections.threads.items.slice(0, 8).map(t => textos.thread(t.title, String(t.facts.phase), t.status)),
48
+ textos.recomendacao(snapshot.conflicts.length, snapshot.gaps.length), textos.final,
54
49
  ].join('\n');
55
50
  }
56
- function runMaestroCli(argv, cwd = process.cwd(), trusted = {}, io = { out: (v) => console.log(v), err: (v) => console.error(v) }) {
51
+ function runMaestroCli(argv, cwd = process.cwd(), trusted = {}, io = { out: (v) => console.log(v), err: (v) => console.error(v) }, textos = locale_maestro_1.MAESTRO_PT_BR) {
57
52
  if (argv.length === 1 && argv[0] === '--help') {
58
- io.out('ork maestro [--json] [--thread ID] [--section NOME --offset N]\nConsulta sem criar ou despachar trabalho. Na conversa, diga: orkastery maestro.');
53
+ io.out(textos.help);
59
54
  return 0;
60
55
  }
61
56
  try {
@@ -94,7 +89,7 @@ function runMaestroCli(argv, cwd = process.cwd(), trusted = {}, io = { out: (v)
94
89
  const context = (0, maestro_discovery_1.discoverMaestro)({ cwd, ...trusted });
95
90
  const snapshot = readMaestro(context, { threadId, offsets: section ? { [section]: offset } : undefined, native: true,
96
91
  host: { tools: ['ork_thread_status', 'ork_observe', 'ork_git_status'], child: false } });
97
- io.out(json ? JSON.stringify(snapshot) : maestroText(snapshot));
92
+ io.out(json ? JSON.stringify(snapshot) : maestroText(snapshot, textos));
98
93
  return 0;
99
94
  }
100
95
  catch (e) {
package/dist/manifest.js CHANGED
@@ -772,7 +772,12 @@ function carregarManifesto(dirInicial = diretorioDoProjeto()) {
772
772
  // Runtime de despacho: so os homologados passam. Um typo aqui viraria erro apenas na
773
773
  // hora do despacho, com a thread ja aberta; reprovar no manifesto e mais barato.
774
774
  const adapterDeRuntime = texto(runtime.adapter, runtimes_1.RUNTIME_PADRAO);
775
- if (!(0, runtimes_1.runtimeConhecido)(adapterDeRuntime)) {
775
+ if ((0, runtimes_1.runtimeConhecido)(adapterDeRuntime) && !(0, runtimes_1.runtimeDoManifesto)(adapterDeRuntime)) {
776
+ // RM-067 (F4): runtime de bloco no setup, nunca o padrao do projeto.
777
+ erros.push(`runtime.adapter fora do padrao do projeto: "${adapterDeRuntime}" entra por ork setup <modo> --bloco N --runtime ` +
778
+ `${adapterDeRuntime} --model <modelo> ou por ork phase run --runtime ${adapterDeRuntime} (o padrao aceita: ${runtimes_1.ORDEM_DOS_RUNTIMES.join(', ')})`);
779
+ }
780
+ else if (!(0, runtimes_1.runtimeDoManifesto)(adapterDeRuntime)) {
776
781
  erros.push(`runtime.adapter desconhecido: "${adapterDeRuntime}" (homologados: ${runtimes_1.ORDEM_DOS_RUNTIMES.join(', ')})`);
777
782
  }
778
783
  const sandboxDoRuntime = texto(runtime.sandbox, codex_1.SANDBOX_PADRAO);
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ENV_VARS_CODEX_MCP = exports.BRAIN_WRITE_TOOLS = exports.BRAIN_READ_TOOLS = exports.TOOLS_FILHO_CODEX = exports.TOOLS_DONO_CODEX = exports.TRANSPORTES_SHIP_MCP = void 0;
36
+ exports.HOSTS_MCP = exports.ENV_VARS_CODEX_MCP = exports.BRAIN_WRITE_TOOLS = exports.BRAIN_READ_TOOLS = exports.TOOLS_FILHO_CODEX = exports.TOOLS_DONO_CODEX = exports.TRANSPORTES_SHIP_MCP = void 0;
37
+ exports.arquivoDoHostMcp = arquivoDoHostMcp;
37
38
  exports.validarGrantsCodex = validarGrantsCodex;
38
39
  exports.politicasFilhoCodex = politicasFilhoCodex;
39
40
  exports.configuracaoServidorMcp = configuracaoServidorMcp;
@@ -54,7 +55,8 @@ const IMPRESSAO_SSH = /^SHA256:[A-Za-z0-9+/]{43}$/;
54
55
  exports.TOOLS_DONO_CODEX = ['ork_thread_new', 'ork_phase_run', 'ork_request_decision'];
55
56
  // RM-037 (rm037defeito, defeito 1): a decisao autonoma da sessao entra com as outras mutacoes do filho;
56
57
  // sem o grant, o codex com approval_policy never recusaria a chamada.
57
- exports.TOOLS_FILHO_CODEX = ['ork_artifact_write', 'ork_claim_add', 'ork_decision_record', 'ork_git_commit', 'ork_verify', 'ork_ship'];
58
+ exports.TOOLS_FILHO_CODEX = ['ork_artifact_write', 'ork_claim_add', 'ork_decision_record', 'ork_request_conduction',
59
+ 'ork_git_commit', 'ork_verify', 'ork_verify_status', 'ork_ship'];
58
60
  // Brain mutation tools are deliberately excluded from the existing opt-in bundle.
59
61
  // A native integration must request exact startup grants plus scoped activation.
60
62
  var company_brain_mcp_1 = require("./company-brain-mcp");
@@ -62,6 +64,11 @@ Object.defineProperty(exports, "BRAIN_READ_TOOLS", { enumerable: true, get: func
62
64
  Object.defineProperty(exports, "BRAIN_WRITE_TOOLS", { enumerable: true, get: function () { return company_brain_mcp_1.BRAIN_WRITE_TOOLS; } });
63
65
  /** Caminho de sessao, nunca credencial. O cliente resolve o valor no ambiente ao iniciar o MCP. */
64
66
  exports.ENV_VARS_CODEX_MCP = ['CODEX_HOME'];
67
+ exports.HOSTS_MCP = ['claude-code', 'codex', 'grok'];
68
+ /** O arquivo do projeto onde cada host le a entrada `orkastery`; o codex e o grok usam TOML com `mcp_servers`. */
69
+ function arquivoDoHostMcp(raiz, host) {
70
+ return host === 'claude-code' ? path.join(raiz, '.mcp.json') : path.join(raiz, host === 'codex' ? '.codex' : '.grok', 'config.toml');
71
+ }
65
72
  function objeto(v) {
66
73
  if (!v || typeof v !== 'object' || Array.isArray(v))
67
74
  throw Error('mcp.install.config.invalid: objeto esperado');
@@ -207,14 +214,14 @@ function migrarEnvVarsCodex(bruto, entrada) {
207
214
  /** O transporte SHIP de cada host do projeto com a entrada orkastery; config que nao se le nao conta. */
208
215
  function transportesDosHosts(raiz) {
209
216
  const achados = [];
210
- for (const host of ['claude-code', 'codex']) {
211
- const arquivo = path.join(raiz, host === 'codex' ? '.codex/config.toml' : '.mcp.json');
217
+ for (const host of exports.HOSTS_MCP) {
218
+ const arquivo = arquivoDoHostMcp(raiz, host), toml = host !== 'claude-code';
212
219
  try {
213
220
  const lido = ler(arquivo);
214
221
  if (!lido)
215
222
  continue;
216
- const bruto = lido.bytes.toString('utf8'), dados = objeto(host === 'codex' ? (0, smol_toml_1.parse)(bruto) : JSON.parse(bruto));
217
- const servidores = objeto(dados[host === 'codex' ? 'mcp_servers' : 'mcpServers']);
223
+ const bruto = lido.bytes.toString('utf8'), dados = objeto(toml ? (0, smol_toml_1.parse)(bruto) : JSON.parse(bruto));
224
+ const servidores = objeto(dados[toml ? 'mcp_servers' : 'mcpServers']);
218
225
  if (!Object.hasOwn(servidores, 'orkastery'))
219
226
  continue;
220
227
  const argv = objeto(servidores.orkastery).args, lista = Array.isArray(argv) ? argv : [], i = lista.indexOf('--ship-transport');
@@ -228,7 +235,7 @@ function instalarMcp(opcoes) {
228
235
  // Ensaio da 0.5.0: os READMEs dos plugins mandavam `--project .`, recusado sem dizer como acertar.
229
236
  if (!path.isAbsolute(opcoes.projeto))
230
237
  throw Error('mcp.install.project.invalid: raiz absoluta obrigatoria; na raiz do projeto, use --project "$PWD"');
231
- if (!['claude-code', 'codex'].includes(opcoes.host))
238
+ if (!exports.HOSTS_MCP.includes(opcoes.host))
232
239
  throw Error('mcp.install.host.invalid');
233
240
  if (opcoes.transporteShip !== undefined && !(0, mcp_transportes_1.ehTransporteShipMcp)(opcoes.transporteShip))
234
241
  throw Error('mcp.install.transport.invalid');
@@ -267,7 +274,9 @@ function instalarMcp(opcoes) {
267
274
  }
268
275
  const gravarFixacaoSePedida = () => { if (fixacao && !opcoes.dryRun)
269
276
  (0, mcp_ship_transporte_1.gravarFixacao)((0, mcp_ship_transporte_1.dirDaFixacao)(raiz), fixacao); };
270
- const pasta = opcoes.host === 'codex' ? path.join(raiz, '.codex') : raiz;
277
+ // RM-067 (F4b): o grok grava como o codex, em TOML; so o claude-code usa o `.mcp.json` da raiz.
278
+ const toml = opcoes.host !== 'claude-code';
279
+ const pasta = path.dirname(arquivoDoHostMcp(raiz, opcoes.host));
271
280
  const validarPasta = () => {
272
281
  try {
273
282
  const st = fs.lstatSync(pasta);
@@ -280,17 +289,17 @@ function instalarMcp(opcoes) {
280
289
  }
281
290
  };
282
291
  validarPasta();
283
- const arquivo = path.join(pasta, opcoes.host === 'codex' ? 'config.toml' : '.mcp.json');
292
+ const arquivo = arquivoDoHostMcp(raiz, opcoes.host);
284
293
  const anterior = ler(arquivo), bruto = anterior?.bytes.toString('utf8') ?? '';
285
294
  const { command: comando, args } = configuracaoServidorMcp(raiz, opcoes.host, undefined, opcoes.transporteShip, opcoes.permissoesFilho);
286
295
  let dados;
287
296
  try {
288
- dados = anterior ? objeto(opcoes.host === 'codex' ? (0, smol_toml_1.parse)(bruto) : JSON.parse(bruto)) : {};
297
+ dados = anterior ? objeto(toml ? (0, smol_toml_1.parse)(bruto) : JSON.parse(bruto)) : {};
289
298
  }
290
299
  catch {
291
300
  throw Error('mcp.install.config.invalid: configuracao existente nao foi alterada');
292
301
  }
293
- const chave = opcoes.host === 'codex' ? 'mcp_servers' : 'mcpServers';
302
+ const chave = toml ? 'mcp_servers' : 'mcpServers';
294
303
  const servidores = dados[chave] === undefined ? {} : objeto(dados[chave]);
295
304
  const existente = Object.hasOwn(servidores, 'orkastery') ? objeto(servidores.orkastery) : undefined;
296
305
  const faltaEnvCodex = opcoes.host === 'codex' && existente !== undefined &&
@@ -320,9 +329,11 @@ function instalarMcp(opcoes) {
320
329
  }
321
330
  }
322
331
  let proximo;
323
- if (opcoes.host === 'codex') {
332
+ if (toml) {
324
333
  // Append preserva comentarios e escolhas do usuario. TOML inline fechado pode impedir a extensao.
325
- proximo = bruto + (bruto.endsWith('\n') || !bruto ? '' : '\n') + (existente ? '' : '\n[mcp_servers.orkastery]\ncommand = ' + JSON.stringify(comando) + '\nargs = ' + JSON.stringify(args) + '\nenv_vars = ' + JSON.stringify([...exports.ENV_VARS_CODEX_MCP]) + '\n');
334
+ // RM-067 (F4b): o grok nao tem a lista de variaveis do codex; a entrada dele e so command e args.
335
+ proximo = bruto + (bruto.endsWith('\n') || !bruto ? '' : '\n') + (existente ? '' : '\n[mcp_servers.orkastery]\ncommand = ' + JSON.stringify(comando) + '\nargs = ' + JSON.stringify(args) + '\n' +
336
+ (opcoes.host === 'codex' ? 'env_vars = ' + JSON.stringify([...exports.ENV_VARS_CODEX_MCP]) + '\n' : ''));
326
337
  if (existente && faltaEnvCodex) {
327
338
  proximo = migrarEnvVarsCodex(proximo, existente);
328
339
  try {
@@ -70,12 +70,11 @@ const preflight_1 = require("./preflight");
70
70
  const modos_1 = require("./modos");
71
71
  const mcp_noctum_1 = require("./mcp-noctum");
72
72
  const versao_1 = require("./versao");
73
- const mcp_verify_1 = require("./mcp-verify");
74
73
  const conducao_1 = require("./conducao");
75
- const fila_pesada_1 = require("./fila-pesada");
76
74
  const decisao_autonoma_1 = require("./decisao-autonoma");
77
75
  const conducao_texto_1 = require("./conducao-texto");
78
76
  const mcp_ship_1 = require("./mcp-ship");
77
+ const grok_1 = require("./adapters/grok");
79
78
  const company_brain_mcp_1 = require("./company-brain-mcp");
80
79
  const claude_bg_1 = require("./adapters/claude-bg");
81
80
  const session_watcher_claude_1 = require("./session-watcher-claude");
@@ -86,6 +85,7 @@ const mcp_experiencia_1 = require("./mcp-experiencia");
86
85
  const mcp_grafo_1 = require("./mcp-grafo");
87
86
  const mcp_conhecimento_1 = require("./mcp-conhecimento");
88
87
  const locale_1 = require("./locale");
88
+ const pedido_conducao_1 = require("./pedido-conducao");
89
89
  const identidade = zod_1.z.string().min(1).max(80).regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/);
90
90
  const daThread = zod_1.z.object({ threadId: identidade }).strict();
91
91
  const daDecisao = daThread.extend({ pedidoId: identidade }).strict();
@@ -113,7 +113,8 @@ const modoDeConducao = zod_1.z.string().trim().min(1).max(40)
113
113
  const nova = zod_1.z.object({ nome: zod_1.z.string().trim().min(1).max(200),
114
114
  modo: modoDeConducao.optional() }).strict();
115
115
  const fase = daThread.extend({ fase: zod_1.z.enum(['GOAL', 'PLAN', 'GO', 'CHECK', 'SHIP', 'MASTER']),
116
- prompt: zod_1.z.string().min(1).max(65536), runtime: zod_1.z.enum(['claude-bg', 'codex']).optional(),
116
+ // RM-067 (F4b): o grok tambem, como o --runtime do CLI, sempre com o model dele.
117
+ prompt: zod_1.z.string().min(1).max(65536), runtime: zod_1.z.enum(['claude-bg', 'codex', 'grok']).optional(),
117
118
  model: zod_1.z.string().trim().min(1).max(200).optional(),
118
119
  effort: zod_1.z.enum(['low', 'medium', 'high', 'xhigh', 'max']).optional(),
119
120
  // RM-056 (D1): o perfil pedido, validado contra o store pelo mesmo caminho do CLI.
@@ -125,8 +126,11 @@ const resposta = (valor) => ({ content: [{ type: 'text', text: JSON.stringify(va
125
126
  function criarServidorMcp(opcoes) {
126
127
  if (!path.isAbsolute(opcoes.projeto))
127
128
  throw Error('mcp.project.invalid: raiz absoluta obrigatoria');
128
- if (!['claude-code', 'codex'].includes(opcoes.host))
129
+ if (!['claude-code', 'codex', 'grok'].includes(opcoes.host))
129
130
  throw Error('mcp.host.invalid');
131
+ // RM-067 (F4b, G1): o servidor do grok so serve a sessao filha; o despacho grava --thread na config da worktree.
132
+ if (opcoes.host === 'grok' && opcoes.threadId === undefined)
133
+ throw Error('mcp.host.child-only: --host grok serve so a sessao filha vinculada a uma thread (--thread), que o despacho do ork grava na config da worktree');
130
134
  if (opcoes.permissoesFilho !== undefined && !['interactive', 'worktree'].includes(opcoes.permissoesFilho))
131
135
  throw Error('mcp.child-permissions.invalid');
132
136
  if (opcoes.threadId !== undefined)
@@ -187,6 +191,18 @@ function criarServidorMcp(opcoes) {
187
191
  };
188
192
  if (opcoes.threadId)
189
193
  thread(opcoes.threadId);
194
+ // RM-067 (F4b, G1): o servidor do grok lista so as ferramentas do perfil filho; o headless nao aprova outra em dialogo.
195
+ const doGrok = opcoes.host === 'grok'
196
+ ? new Set((0, grok_1.ferramentasServidasAoGrok)(opcoes.permissoesFilho ?? 'interactive', (0, mcp_grafo_1.grafoLigado)((0, manifest_1.exigirManifesto)(raiz).manifesto))) : null;
197
+ // RM-067 (F4c, D4): a lista do despacho e um subconjunto da uniao do perfil filho; fora dela, ou sem o host grok, recusa.
198
+ if (opcoes.ferramentas !== undefined) {
199
+ const pedidas = opcoes.ferramentas;
200
+ if (!doGrok || pedidas.some(n => !doGrok.has(n)) || new Set(pedidas).size !== pedidas.length)
201
+ throw Error('mcp.tools.invalid: a lista do despacho sai do perfil filho do grok');
202
+ for (const nome of [...doGrok])
203
+ if (!pedidas.includes(nome))
204
+ doGrok.delete(nome);
205
+ }
190
206
  const pendencias = (id) => {
191
207
  const t = thread(id), eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, id)), contexto = (0, hitl_gates_1.contextoHitl)(raiz, id);
192
208
  const pedidos = [(0, hitl_presentation_1.pedidoHitlAberto)(raiz, id, t.faseAtual, null),
@@ -195,7 +211,7 @@ function criarServidorMcp(opcoes) {
195
211
  // e so ele. Nenhum outro canal mcp-local sai `disponivel` daqui por suposicao.
196
212
  return pedidos.filter(p => p && eventos.some(e => e.tipo === 'hitl_requested' && e.contexto === contexto &&
197
213
  e.pedido?.id === p.id)).map(p => ({ pedido: p, estado: (0, hitl_contract_1.estadoDoPedido)(p),
198
- canais: (0, hitl_presentation_1.ofertaDoPedido)(p, [opcoes.host]), prazoLocal: (0, hitl_presentation_1.prazoLocalDoPedido)(p) }));
214
+ canais: (0, hitl_presentation_1.ofertaDoPedido)(p, opcoes.host === 'grok' ? [] : [opcoes.host]), prazoLocal: (0, hitl_presentation_1.prazoLocalDoPedido)(p) }));
199
215
  };
200
216
  const fases = (id) => {
201
217
  thread(id);
@@ -334,6 +350,8 @@ function criarServidorMcp(opcoes) {
334
350
  function registrarTool(nome, config, executar) {
335
351
  if (opcoes.threadId && ['ork_thread_new', 'ork_phase_run', 'ork_request_decision', 'ork_request_master_note', 'ork_preflight'].includes(nome))
336
352
  return;
353
+ if (doGrok && !doGrok.has(nome))
354
+ return;
337
355
  const entrada = config.inputSchema.extend({ projeto: campoProjeto.optional() });
338
356
  const schema = converterSchema(entrada, { $refStrategy: 'none' });
339
357
  ferramentas.set(nome, { tool: { name: nome, description: config.description, annotations: config.annotations,
@@ -347,6 +365,7 @@ function criarServidorMcp(opcoes) {
347
365
  }
348
366
  server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({ tools: [...ferramentas.values()].map(f => f.tool) }));
349
367
  server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request, extra) => {
368
+ opcoes.emCurso?.(1);
350
369
  try {
351
370
  const f = ferramentas.get(request.params.name);
352
371
  if (!f)
@@ -358,12 +377,16 @@ function criarServidorMcp(opcoes) {
358
377
  return { ...resposta(e.recusa), isError: true };
359
378
  return { ...resposta({ erro: e.message }), isError: true };
360
379
  }
380
+ finally {
381
+ opcoes.emCurso?.(-1);
382
+ }
361
383
  });
362
384
  const conexaoLocal = (0, node_crypto_1.randomUUID)();
363
385
  // RM-059 (F9, G3): a caixa de saida do Mensageiro de Sessoes so existe no servidor do dono do Claude Code, na memoria:
364
386
  // a resposta a uma sessao claude-bg que entra pelo dialogo deste servidor sai por ela, e o texto nunca vai a disco.
365
387
  const caixa = opcoes.host === 'claude-code' && !opcoes.threadId ? (0, entrega_por_mod_1.novaCaixaDeSaida)() : null;
366
- const ingresso = (0, hitl_local_1.criarIngressoLocal)(raiz, { host: opcoes.host, connectionId: conexaoLocal }, async (pedido, signal) => {
388
+ // RM-067 (F4b, G5): o headless do grok nao tem dialogo, e a sessao filha nao pede decisao nem nota: sem ingresso local.
389
+ const ingresso = opcoes.host === 'grok' ? null : (0, hitl_local_1.criarIngressoLocal)(raiz, { host: opcoes.host, connectionId: conexaoLocal }, async (pedido, signal) => {
367
390
  carregar();
368
391
  thread(pedido.thread);
369
392
  // D12: pergunta nativa que aceita texto NAO vira menu. Um menu sobre pergunta aberta
@@ -388,14 +411,14 @@ function criarServidorMcp(opcoes) {
388
411
  }, { caixa });
389
412
  // RM-059 (fatia F8, T8.1): a nota do MASTER pelo mesmo ingresso local. O formulario e fixo (a nota de 0 a 5 e o
390
413
  // porque); sem a capacidade de formulario no cliente, a recusa vem antes de qualquer escrita.
391
- const ingressoDaNota = (0, master_nota_local_1.criarIngressoDaNota)(raiz, { host: opcoes.host, connectionId: conexaoLocal }, async (apresentacao, signal) => {
414
+ const ingressoDaNota = opcoes.host === 'grok' ? null : (0, master_nota_local_1.criarIngressoDaNota)(raiz, { host: opcoes.host, connectionId: conexaoLocal }, async (apresentacao, signal) => {
392
415
  carregar();
393
416
  thread(apresentacao.thread);
394
417
  const r = await server.elicitInput({ mode: 'form', message: apresentacao.mensagem,
395
418
  requestedSchema: apresentacao.esquema }, { signal, timeout: 300000 });
396
419
  return r.action === 'accept' ? { action: 'accept', content: r.content } : { action: r.action };
397
420
  }, () => Boolean(server.getClientCapabilities()?.elicitation?.form));
398
- server.onclose = () => { ingresso.fechar(); ingressoDaNota.fechar(); };
421
+ server.onclose = () => { ingresso?.fechar(); ingressoDaNota?.fechar(); };
399
422
  (0, company_brain_mcp_1.registerBrainTools)(registrarTool, carregar, thread, opcoes.brainWrites ?? []);
400
423
  (0, mcp_experiencia_1.registrarConsultasExperiencia)(registrarTool, { raiz, carregar, transporte: opcoes.transporteShip ?? 'github-ssh' });
401
424
  // RM-026 K7 (fatia 2): o conhecimento escrito, só leitura, do projeto fixado; também na sessão filha vinculada.
@@ -432,23 +455,20 @@ function criarServidorMcp(opcoes) {
432
455
  const r = await (0, mcp_ship_1.shipMcp)(perfilShip, args, extra.signal);
433
456
  return { ...resposta(r), ...(r.ok ? {} : { isError: true }) };
434
457
  });
435
- registrarTool('ork_verify', { description: 'Reexecuta claims e verificadores do manifesto na worktree, em sandbox e com prazo total de tres minutos. Registra resultado real; falhas bloqueiam a verificacao.',
458
+ registrarTool('ork_verify', { description: 'Inicia uma rodada assíncrona do verify canônico no processo do servidor, vinculada à thread e ao despacho. Devolve imediatamente o UUID; repetir enquanto viva reutiliza a rodada.',
436
459
  inputSchema: daThread, annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId }) => {
437
460
  thread(threadId);
438
- livre(threadId);
439
- try {
440
- const r = (0, mcp_verify_1.verificarMcp)(raiz, threadId, conducao);
441
- return { ...resposta(r), ...(r.ok ? {} : { isError: true }) };
442
- }
443
- catch (e) {
444
- // I-36 (T18): a mesma recusa tipada do CLI, com o mesmo texto, sem reescrever nada no host.
445
- if (e instanceof conducao_1.ErroDeConducao)
446
- return { ...resposta(e.recusa), isError: true };
447
- // RM-058 N2 (A6 do CHECK): a fila pesada que nao deu a vez no prazo responde como a conducao.
448
- if (e instanceof fila_pesada_1.ErroDaFilaPesada)
449
- return { ...resposta(e.recusa), isError: true };
450
- throw e;
451
- }
461
+ const { iniciarVerifyMcp } = await Promise.resolve().then(() => __importStar(require('./mcp-verify-async')));
462
+ const r = iniciarVerifyMcp(raiz, threadId, { host: opcoes.host, despacho: opcoes.dispatchId ?? null });
463
+ return { ...resposta(r), ...(r.estado === 'falhou' ? { isError: true } : {}) };
464
+ });
465
+ registrarTool('ork_verify_status', { description: 'Consulta uma rodada assíncrona do verify por UUID: na fila, rodando com a lane atual, concluída com o veredito completo do CLI ou falha tipada. Não inicia nem duplica rodada.',
466
+ inputSchema: daThread.extend({ rodadaId: zod_1.z.string().uuid() }).strict(), annotations: { readOnlyHint: true, destructiveHint: false } }, async ({ threadId, rodadaId }) => {
467
+ thread(threadId);
468
+ const { consultarVerifyMcp } = await Promise.resolve().then(() => __importStar(require('./mcp-verify-async')));
469
+ const r = consultarVerifyMcp(raiz, threadId, rodadaId);
470
+ const reprovou = r.estado === 'falhou' || (r.estado === 'concluido' && r.veredito?.ok === false);
471
+ return { ...resposta(r), ...(reprovou ? { isError: true } : {}) };
452
472
  });
453
473
  registrarTool('ork_git_commit', { description: 'Commita somente paths com claims e HEAD esperado na worktree da thread. Recusa hooks/filtros ativos; preserva configuracao. Commit local nao e SHIP.',
454
474
  inputSchema: daThread.extend({ expectedHead: zod_1.z.string().regex(/^[a-f0-9]{40}$/),
@@ -595,16 +615,18 @@ function criarServidorMcp(opcoes) {
595
615
  livre(threadId);
596
616
  return resposta((0, hitl_gates_1.abrirPedidoGate)(raiz, threadId, motivo));
597
617
  });
598
- registrarTool('ork_request_decision', { description: 'Apresenta pedido existente ao dono por dialogo nativo. Somente IDs; nunca forneca resposta nos argumentos.',
599
- inputSchema: daDecisao, annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId, pedidoId }, extra) => {
600
- thread(threadId);
601
- return resposta(await ingresso.solicitar(threadId, pedidoId, extra.signal));
602
- });
603
- registrarTool('ork_request_master_note', { description: 'Pede ao dono, pelo dialogo nativo do host, a nota de 0 a 5 e o porque de uma entrega. Somente o threadId; nunca forneca nota nem porque nos argumentos.',
604
- inputSchema: daThread, annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId }, extra) => {
605
- thread(threadId);
606
- return resposta(await ingressoDaNota.solicitar(threadId, extra.signal));
607
- });
618
+ if (ingresso)
619
+ registrarTool('ork_request_decision', { description: 'Apresenta pedido existente ao dono por dialogo nativo. Somente IDs; nunca forneca resposta nos argumentos.',
620
+ inputSchema: daDecisao, annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId, pedidoId }, extra) => {
621
+ thread(threadId);
622
+ return resposta(await ingresso.solicitar(threadId, pedidoId, extra.signal));
623
+ });
624
+ if (ingressoDaNota)
625
+ registrarTool('ork_request_master_note', { description: 'Pede ao dono, pelo dialogo nativo do host, a nota de 0 a 5 e o porque de uma entrega. Somente o threadId; nunca forneca nota nem porque nos argumentos.',
626
+ inputSchema: daThread, annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId }, extra) => {
627
+ thread(threadId);
628
+ return resposta(await ingressoDaNota.solicitar(threadId, extra.signal));
629
+ });
608
630
  // RM-059 (F9, T9.1): o Mensageiro de Sessoes nas duas pontas. Nenhuma das duas entra no --allowedTools do modelo (D8):
609
631
  // quem chama e o mod ork-mensageiro, e nenhuma responde, aprova ou abre pedido.
610
632
  if (caixa)
@@ -623,6 +645,13 @@ function criarServidorMcp(opcoes) {
623
645
  });
624
646
  if (opcoes.threadId && opcoes.dispatchId) {
625
647
  const despacho = opcoes.dispatchId;
648
+ registrarTool('ork_request_conduction', { description: 'Registra um pedido tipado desta sessao para a conducao, com comando ork exato. Nao executa o comando, nao aprova gate e nao responde pelo dono.',
649
+ inputSchema: daThread.extend({ motivo: zod_1.z.enum(pedido_conducao_1.MOTIVOS_DE_PEDIDO_A_CONDUCAO), detalhe: zod_1.z.string().trim().min(1).max(2000),
650
+ comando: zod_1.z.string().trim().min(1).max(1000) }).strict(),
651
+ annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId, motivo, detalhe, comando }) => {
652
+ thread(threadId);
653
+ return resposta((0, pedido_conducao_1.registrarPedidoAConducao)(raiz, threadId, { despacho, motivo, detalhe, comando, host: opcoes.host }));
654
+ });
626
655
  registrarTool('ork_session_inbox', { description: 'Lado receptor do Mensageiro de Sessoes na sessao de fase deste despacho: confere e reserva uma vez a resposta do dono que chegou de outra sessao (conferir, com o prazo ate) e, depois de ela entrar na fila, grava o recibo (confirmar). A sessao sai do despacho deste servidor, nunca de argumento. Nao responde nem aprova pedido.',
627
656
  inputSchema: daThread.extend({ operacao: zod_1.z.enum(['conferir', 'confirmar']), texto: zod_1.z.string().max(entrega_por_mod_1.LIMITE_DA_MENSAGEM),
628
657
  envioId: zod_1.z.string().uuid().optional(), ate: zod_1.z.string().max(40).optional() }).strict(),