@orkastery/cli 0.5.0 → 0.5.1

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 (63) hide show
  1. package/adapters/claude-code/README.md +11 -2
  2. package/adapters/claude-code/commands/onboarding.md +3 -2
  3. package/adapters/openclaw/README.md +11 -0
  4. package/adapters/openclaw/dist/index.js +1 -1
  5. package/adapters/openclaw/openclaw.plugin.json +1 -1
  6. package/adapters/openclaw/package.json +1 -1
  7. package/adapters/openclaw/src/index.ts +1 -1
  8. package/dist/adapters/claude-bg.js +20 -6
  9. package/dist/auditrun.js +1 -1
  10. package/dist/claim-lint.js +3 -1
  11. package/dist/docs.js +71 -3
  12. package/dist/doctor.js +209 -32
  13. package/dist/entrega-pr.js +7 -0
  14. package/dist/fabrica-estado.js +21 -3
  15. package/dist/fix.js +3 -3
  16. package/dist/hitl-resumo.js +24 -1
  17. package/dist/hosts.js +7 -3
  18. package/dist/index.js +42 -14
  19. package/dist/init.js +11 -5
  20. package/dist/integracoes-locais.js +2 -0
  21. package/dist/intelligence-graph-cli.js +181 -27
  22. package/dist/intelligence-graph-contract.js +71 -12
  23. package/dist/intelligence-graph-extract-md.js +41 -23
  24. package/dist/intelligence-graph-extract-ts.js +181 -11
  25. package/dist/intelligence-graph-extract.js +186 -9
  26. package/dist/intelligence-graph-index.js +205 -24
  27. package/dist/intelligence-graph-repo.js +10 -0
  28. package/dist/leases.js +16 -0
  29. package/dist/ledger.js +9 -0
  30. package/dist/licoes.js +5 -4
  31. package/dist/liveness.js +2 -1
  32. package/dist/maestro-runtime.js +3 -0
  33. package/dist/manifest.js +24 -0
  34. package/dist/mcp-artifacts.js +2 -0
  35. package/dist/mcp-git.js +60 -12
  36. package/dist/mcp-grafo-worker.js +91 -0
  37. package/dist/mcp-grafo.js +233 -0
  38. package/dist/mcp-install.js +2 -1
  39. package/dist/mcp-server.js +9 -0
  40. package/dist/mcp-ship.js +2 -0
  41. package/dist/mcp-verify.js +3 -1
  42. package/dist/network-roadmap.js +5 -5
  43. package/dist/ocupacao.js +6 -2
  44. package/dist/onboarding.js +9 -4
  45. package/dist/orquestracao.js +2 -1
  46. package/dist/parado-no-condutor.js +933 -0
  47. package/dist/policies.js +27 -2
  48. package/dist/prova-ativacao.js +345 -0
  49. package/dist/pulse-delivery.js +27 -6
  50. package/dist/pulse.js +53 -3
  51. package/dist/roadmap-status.js +142 -7
  52. package/dist/runtime-context.js +5 -1
  53. package/dist/sessoes-inventario.js +7 -1
  54. package/dist/sessoes.js +4 -1
  55. package/dist/ship.js +25 -1
  56. package/dist/thread.js +21 -2
  57. package/dist/util.js +71 -4
  58. package/dist/verify.js +2 -2
  59. package/dist/worktree.js +29 -6
  60. package/eval/casos/onboarding.json +1 -1
  61. package/package.json +1 -1
  62. package/skills/core/onboarding/SKILL.md +3 -2
  63. package/skills/phases/ship-release/SKILL.md +6 -3
@@ -81,6 +81,10 @@ function registrarEntregaPorPr(carregado, threadId, opcoes = {}) {
81
81
  if (ci.required && !ci.ok) {
82
82
  return resultado(threadId, 'recusada', `sem CI verde no head do PR: ${ci.detail}`, { ...merge, ci });
83
83
  }
84
+ // RM-037 (fatia 3, defeito 6): o ensaio confere tudo e para aqui, sem ledger, fase nem fabrica.
85
+ if (opcoes.dryRun) {
86
+ return resultado(threadId, 'registraria', `ensaio: registraria ship_done pelo merge ${merge.mergeSha.slice(0, 7)} do PR (nada gravado)`, { ...merge, ci });
87
+ }
84
88
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.shipConcluido, {
85
89
  de: thread.base?.branch ?? null,
86
90
  para: base,
@@ -174,6 +178,9 @@ function registrarEntregaExternaPorPr(carregado, threadId, opcoes) {
174
178
  if (ci && !ci.ok) {
175
179
  return resultado(threadId, 'recusada', `sem CI verde no head do PR: ${ci.detail}`, { mergeSha, headSha, ci });
176
180
  }
181
+ if (opcoes.dryRun) {
182
+ return resultado(threadId, 'registraria', `ensaio: registraria ship_done pelo merge ${mergeSha.slice(0, 7)} do PR #${n} de ${repo} (nada gravado)`, { mergeSha, headSha, ci });
183
+ }
177
184
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.shipConcluido, {
178
185
  de: thread.base?.branch ?? null,
179
186
  para: `${repo}:${base}`,
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.PULSACAO_MS = exports.DIR_DA_FABRICA = exports.BRANCH_DA_FABRICA = exports.CONTRATO_MAQUINA = void 0;
36
+ exports.LIMIAR_SEM_BATIDA_MS = exports.PULSACAO_MS = exports.DIR_DA_FABRICA = exports.BRANCH_DA_FABRICA = exports.CONTRATO_MAQUINA = void 0;
37
37
  exports.despachoDaThread = despachoDaThread;
38
38
  exports.runtimeDaThread = runtimeDaThread;
39
39
  exports.arquivoDaMaquina = arquivoDaMaquina;
@@ -76,6 +76,7 @@ const horario_1 = require("./horario");
76
76
  const ledger_1 = require("./ledger");
77
77
  const modos_1 = require("./modos");
78
78
  const orquestracao_1 = require("./orquestracao");
79
+ const parado_no_condutor_1 = require("./parado-no-condutor");
79
80
  const roadmap_reservas_1 = require("./roadmap-reservas");
80
81
  const thread_1 = require("./thread");
81
82
  const util_1 = require("./util");
@@ -90,6 +91,12 @@ const PREFIXO = 'fabrica';
90
91
  const TENTATIVAS = 5;
91
92
  /** Retrato igual ao ultimo publicado so volta ao remoto depois disto: e o sinal de vida da maquina. */
92
93
  exports.PULSACAO_MS = 60 * 60 * 1000;
94
+ /**
95
+ * Maquina sem retrato novo ha mais disto esta sem batida: o mesmo limiar da rede (RM-053, `SEM_BATIDA_MS`).
96
+ * RM-037 (fatia 4): mora aqui, junto da pulsacao, porque o status do roadmap tambem o le; o panorama da
97
+ * rede o reexporta.
98
+ */
99
+ exports.LIMIAR_SEM_BATIDA_MS = 3 * 60 * 60 * 1000;
93
100
  const ARQUIVO_DA_MARCA = 'fabrica-publicada.json';
94
101
  const ARQUIVO_DO_LOG = 'fabrica.log';
95
102
  /** O trio do ultimo `phase_dispatch` do ledger da thread; tudo `null` quando nao ha despacho legivel. */
@@ -155,9 +162,20 @@ function retratoDaMaquina(carregado, opcoes = {}) {
155
162
  const entregas = entregasNaBase(raiz, carregado.manifesto.worktree.base_branch, remoto);
156
163
  const itemDaThread = new Map((0, roadmap_reservas_1.reservasLocais)(raiz, remoto).filter((r) => r.thread).map((r) => [r.thread, r.item]));
157
164
  const threads = itens.map(({ thread: t, raiz: raizDoPerfil }) => {
158
- const pausa = linhas.get(t.id)?.pausas[0];
159
165
  const entregue = entregas.get(t.id) ?? null;
160
- const esperaVoce = !entregue && linhas.get(t.id)?.precisaDeHumano === true;
166
+ // RM-037 (fatia 4): o fim de turno sem pergunta e do condutor, e as outras maquinas nao o leem como espera
167
+ // do dono. Sai so a pausa que o observador abriu nele; outra pausa da thread continua contando.
168
+ let espera = null;
169
+ try {
170
+ espera = (0, parado_no_condutor_1.esperaDoCondutor)(t, (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raizDoPerfil, t.id)), quando);
171
+ }
172
+ catch {
173
+ espera = null;
174
+ }
175
+ const pausas = (linhas.get(t.id)?.pausas ?? []).filter((p) => !(espera && p.motivo === 'human.pending' && p.fonte === 'ledger' &&
176
+ p.fase === (espera.fase ?? t.faseAtual)));
177
+ const pausa = pausas[0];
178
+ const esperaVoce = !entregue && pausas.some((p) => p.sessaoViva !== true);
161
179
  return {
162
180
  id: t.id, nome: curto(t.nome, 100), modo: (0, modos_1.tagDoModo)(t.modo), fase: t.faseAtual, status: t.status,
163
181
  roadmap: t.roadmap ?? itemDaThread.get(t.id) ?? null, branch: t.base?.branch ?? null,
package/dist/fix.js CHANGED
@@ -150,7 +150,7 @@ function derivarCorrecoes(thread, rodada, resultado, idsUsados) {
150
150
  }
151
151
  for (const cmd of resultado.regressoes) {
152
152
  nascer('verify.regression', `comando ${cmd.nome}`, `REGRESSAO: "${cmd.comando}" passava na baseline gravada antes do GO (commit ` +
153
- `${resultado.baseline?.commit.slice(0, 8) ?? 'desconhecido'}) e falha agora. Este defeito ` +
153
+ `${resultado.baseline ? (0, util_1.shaCurto)(resultado.baseline.commit) : 'desconhecido'}) e falha agora. Este defeito ` +
154
154
  'e desta thread, nao divida pre-existente. Corrija ate o comando voltar a passar.', [cmd.comando], `codigo ${cmd.code}:\n${cmd.resumo}`);
155
155
  }
156
156
  for (const cmd of resultado.falhasSemBaseline) {
@@ -339,7 +339,7 @@ function reverificarSobConducao(carregado, threadId, opcoes) {
339
339
  veredito = 'PASSOU';
340
340
  razao =
341
341
  `${vereditos.length} correcao(oes) aprovada(s) por comando reexecutado no HEAD real` +
342
- (verify ? `, com o verify completo verde no commit ${verify.commit.slice(0, 8)}` : '');
342
+ (verify ? `, com o verify completo verde no commit ${(0, util_1.shaCurto)(verify.commit)}` : '');
343
343
  }
344
344
  else if (rodadas >= limite) {
345
345
  veredito = 'BLOQUEADO';
@@ -459,7 +459,7 @@ function textoDoReverify(r) {
459
459
  }
460
460
  if (r.verify) {
461
461
  linhas.push('');
462
- linhas.push(`Verify completo no HEAD ${r.verify.commit.slice(0, 8)}: ${r.verify.ok ? 'verde' : `reprovado (${r.verify.motivos.join(', ')})`}`);
462
+ linhas.push(`Verify completo no HEAD ${(0, util_1.shaCurto)(r.verify.commit)}: ${r.verify.ok ? 'verde' : `reprovado (${r.verify.motivos.join(', ')})`}`);
463
463
  }
464
464
  linhas.push('');
465
465
  linhas.push(`Veredito final: ${r.veredito}`);
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SEM_PERGUNTA_NO_RESUMO = exports.TETO_DE_DECISOES_DETALHADAS = exports.TETO_DE_ESPERAS_POR_MAQUINA = exports.TETO_DE_THREADS_NOMEADAS = exports.PERGUNTA_DO_RESUMO = exports.CONTRATO_RESUMO = void 0;
3
+ exports.SEM_PERGUNTA_NO_RESUMO = exports.TETO_DE_DECISOES_DETALHADAS = exports.TETO_DE_ESPERAS_POR_MAQUINA = exports.TETO_DE_PARADOS_NO_CONDUTOR = exports.TETO_DE_THREADS_NOMEADAS = exports.PERGUNTA_DO_RESUMO = exports.CONTRATO_RESUMO = void 0;
4
4
  exports.resumirHitl = resumirHitl;
5
+ exports.linhaDoParadoNoCondutor = linhaDoParadoNoCondutor;
6
+ exports.linhasDoCondutor = linhasDoCondutor;
5
7
  exports.linhaDosTecnicos = linhaDosTecnicos;
6
8
  exports.linhasDasOutrasMaquinas = linhasDasOutrasMaquinas;
7
9
  exports.linhasDasDecisoes = linhasDasDecisoes;
@@ -55,8 +57,27 @@ function resumirHitl(itens, opcoes) {
55
57
  ...(opcoes.outrasMaquinas?.length ? { outrasMaquinas: opcoes.outrasMaquinas.map(m => ({ ...m, esperando: [...m.esperando] })) } : {}),
56
58
  tecnicos: tecnicos.length,
57
59
  threadsTecnicas: [...new Set(tecnicos.map(i => i.thread).filter((t) => !!t))].sort(),
60
+ ...(opcoes.paradosNoCondutor?.length ? { paradosNoCondutor: opcoes.paradosNoCondutor.map(p => ({ thread: p.thread, caso: p.caso,
61
+ desdeEm: p.desdeEm, proximoPasso: p.proximoPasso })) } : {}),
58
62
  };
59
63
  }
64
+ /** Quantas linhas do condutor o resumo mostra antes de contar o resto. */
65
+ exports.TETO_DE_PARADOS_NO_CONDUTOR = 5;
66
+ /**
67
+ * RM-037 (fatia 4): "<thread> parado no condutor desde HH:MM: <proximo passo>", a mesma frase no pulse,
68
+ * no resumo dos dois canais e no status do roadmap. O horario sai no fuso do dono.
69
+ */
70
+ function linhaDoParadoNoCondutor(p, opcoes) {
71
+ const { desdeEm: desde } = p;
72
+ return `${p.thread} parado no condutor desde ${(0, horario_1.formatarHora)(desde, opcoes)}: ${p.proximoPasso}`;
73
+ }
74
+ /** As linhas do condutor no resumo, uma por thread, com o resto contado. */
75
+ function linhasDoCondutor(r, marcador, recuo) {
76
+ const parados = r.paradosNoCondutor ?? [];
77
+ const mostradas = parados.slice(0, exports.TETO_DE_PARADOS_NO_CONDUTOR), sobra = parados.length - mostradas.length;
78
+ return [...mostradas.map(p => `${marcador}${linhaDoParadoNoCondutor(p, { agora: r.consultadoEm })}`),
79
+ ...(sobra > 0 ? [`${recuo}e mais ${sobra}: ork pulse`] : [])];
80
+ }
60
81
  /** RM-048 (D6): a linha do que e tecnico, igual nos dois canais. Nao pede nada ao dono. */
61
82
  function linhaDosTecnicos(r) {
62
83
  const nomes = r.threadsTecnicas.length ? ` (${nomearThreads(r.threadsTecnicas)})` : '';
@@ -180,6 +201,7 @@ function textoTelegram(r, codigo) {
180
201
  `❓ ${linhaDasPerguntas(r.prontas)}`,
181
202
  ...(r.tecnicos ? [`🔧 ${linhaDosTecnicos(r)}`] : []),
182
203
  ...(r.consertos ? [`🔧 ${linhaDosConsertos(r.consertos)}`] : []),
204
+ ...(r.paradosNoCondutor?.length ? ['', ...linhasDoCondutor(r, '🚧 ', ' ')] : []),
183
205
  ...(r.acumuladas ? ['', `📥 ${linhaDoLoteGuardado(r.acumuladas)}`] : []),
184
206
  ...(r.decisoes.length || r.acimaDoLimiar.length ? ['', ...linhasDasDecisoes(r, '🧭 ', ' ')] : []),
185
207
  ...(r.outrasMaquinas?.length ? ['', ...linhasDasOutrasMaquinas(r, '🖥️ ', ' ')] : []),
@@ -210,6 +232,7 @@ function textoTerminal(r, codigo) {
210
232
  ? ['', ` threads travadas (${r.threadsBloqueadas.length}): ${nomearThreads(r.threadsBloqueadas)}`] : []),
211
233
  ...(r.tecnicos ? ['', ` ${linhaDosTecnicos(r)}`] : []),
212
234
  ...(r.consertos ? ['', ` ${linhaDosConsertos(r.consertos)}`] : []),
235
+ ...(r.paradosNoCondutor?.length ? ['', ...linhasDoCondutor(r, ' ', ' ')] : []),
213
236
  ...(r.acumuladas ? ['', ` ${linhaDoLoteGuardado(r.acumuladas)}`] : []),
214
237
  ...(r.decisoes.length || r.acimaDoLimiar.length ? ['', ...linhasDasDecisoes(r, '', ' ').map(l => l.startsWith(' ') ? l : ` ${l}`)] : []),
215
238
  ...(r.outrasMaquinas?.length ? ['', ...linhasDasOutrasMaquinas(r, '', ' ').map(l => l.startsWith(' ') ? l : ` ${l}`)] : []),
package/dist/hosts.js CHANGED
@@ -92,8 +92,8 @@ exports.HOSTS = {
92
92
  pitfalls: [
93
93
  {
94
94
  titulo: 'manifesto sem os caminhos das skills instala limpo e nao expoe nada',
95
- detalhe: 'o plugin auto-descobre skills/<nome>/SKILL.md e para ai: ele nao desce nos buckets (core/, phases/, reviewers/, ...) que este catalogo usa, entao o plugin.json declara os 17 caminhos um a um',
96
- prova: 'claude plugin details orkastery # a contagem precisa bater com os SKILL.md em disco',
95
+ detalhe: 'o plugin auto-descobre skills/<nome>/SKILL.md e para ai: ele nao desce nos buckets (core/, phases/, reviewers/, ...) que este catalogo usa, entao o plugin.json declara cada caminho de skill, um a um',
96
+ prova: 'claude plugin details orkastery # Skills (N) soma as skills do plugin.json e os comandos de commands/',
97
97
  },
98
98
  {
99
99
  titulo: 'duas copias do catalogo divergem',
@@ -510,8 +510,12 @@ function textoDosPitfalls(host) {
510
510
  /** Texto de `ork adapter install`. */
511
511
  function textoDaInstalacao(r) {
512
512
  const linhas = [];
513
+ // Ensaio da 0.5.0: com o pacote ativo e pulado por aviso (catalogo fora do projeto), a linha dizia
514
+ // "desativada"; o aviso logo abaixo diz o motivo.
513
515
  if (r.experiencia)
514
- linhas.push(`Experiência: ${r.experiencia.ativa ? 'ativação preparada' : 'desativada ou sem integração de skills'}${r.experiencia.skill ? ` (${r.experiencia.skill})` : ''}.`);
516
+ linhas.push(`Experiência: ${r.experiencia.ativa ? 'ativação preparada'
517
+ : r.experiencia.aviso ? 'pacote pulado nesta instalação, veja o aviso abaixo' : 'desativada ou sem integração de skills'}` +
518
+ `${r.experiencia.skill ? ` (${r.experiencia.skill})` : ''}.`);
515
519
  if (r.experiencia?.aviso)
516
520
  linhas.push(`Aviso: ${r.experiencia.aviso}`);
517
521
  linhas.push(r.dryRun
package/dist/index.js CHANGED
@@ -227,11 +227,11 @@ Uso: ork [--projeto <nome|caminho>] <comando> [argumentos]
227
227
  modos Tabela dos ${modos_1.ORDEM_DOS_MODOS.length} modos de conducao vivos por #TAG
228
228
 
229
229
  setup Pauta da entrevista #setup: runtime/modelo/esforco
230
+ por bloco de cada modo (default claude-bg/opus/high; #Fast: sonnet)
230
231
  onboarding [show|set <etapa>|reset [etapa]] Pauta e respostas do projeto (9 etapas)
231
- [--conteudo JSON] [--por Q] [--json] Valores secretos somente em ~/.hermes/.env
232
+ [--conteudo JSON] [--por Q] [--json] Segredos ficam ${onboarding_1.ONDE_FICAM_OS_SEGREDOS}
232
233
  [--reset [etapa]] Reset seletivo ou total, idempotente
233
234
  onboarding sync [--json] Publicação opcional na memória, com degradação
234
- por bloco de cada modo (default claude-bg/opus/high; #Fast: sonnet)
235
235
  experiencia show [--json] Preferências efetivas; configure por onboarding set maestro --conteudo '{"owner":{"experience":true}}'
236
236
  experiencia uninstall <host> [--dry-run] [--json]
237
237
  Remove o bloco de Claude Code/Codex; sem --dry-run aplica a remoção
@@ -378,14 +378,18 @@ Uso: ork [--projeto <nome|caminho>] <comando> [argumentos]
378
378
  [--dry-run] [--json] com tokens e custo estimados; --dry-run nao chama o provider
379
379
 
380
380
  grafo indexar [--verificar] [--forcar] Indice do grafo de codigo do HEAD limpo (RM-031 KG3) no estado do projeto:
381
- [--json] pastas 0700, chave por revisao e extrator, idempotente; --verificar
382
- confere contrato, bytes e determinismo; precisa de typescript e micromark
381
+ [--json] pastas 0700, chave por revisao e extrator, idempotente; incremental (KG4)
382
+ a partir do indice ancestral, ou completo com o motivo; --forcar extrai
383
+ completo; --verificar confere contrato, bytes, determinismo e o incremental
384
+ contra a completa; precisa de typescript e micromark
383
385
  grafo status [--json] Indices guardados, o do HEAD, os analisadores e o tamanho
384
386
  grafo vizinhos <no> [--profundidade N] Vizinhanca de arquivo ou simbolo, com extrator e evidencia de cada aresta
385
387
  [--sentido entrada|saida|ambos] [--tipo T,...] [--limite N] [--json]
386
388
  grafo chamadores <simbolo> Quem chama (arestas calls que chegam) [--profundidade N] [--limite N] [--json]
387
389
  grafo importadores <arquivo|simbolo> Quem importa (arestas imports que chegam) [--profundidade N] [--limite N] [--json]
388
390
  grafo caminho <de> <para> Menor caminho pelas arestas [--sentido saida|entrada|ambos] [--tipo T,...] [--json]
391
+ [--json --teto-bytes N] Nas quatro consultas (KG5): JSON compacto de no maximo N bytes; as arestas mais
392
+ longe do alvo saem ate caber, e o caminho que nao cabe recusa
389
393
  grafo amostra [--por-estrato N] Amostra de arestas para auditoria manual; --conferir ARQ confere a auditada
390
394
  grafo limpar [--tudo] [--json] Apaga os indices que nao sao do HEAD e as sobras com mais de uma hora
391
395
 
@@ -393,6 +397,7 @@ Uso: ork [--projeto <nome|caminho>] <comando> [argumentos]
393
397
  ship registrar-pr <thread-id>|--todas A entrega feita por PR vira ship_done: merge ship(<thread>) na base
394
398
  [--remoto R] [--json] remota e CI verde no head do PR; depois, ork master --aceitar-omissao
395
399
  [--repo <dono/nome> --pr <n>] PR mesclado em repositorio externo de ci.external_repositories
400
+ [--dry-run] Ensaio: as mesmas conferencias, sem gravar ship_done, fase nem fabrica
396
401
  [--de <branch>] [--remoto origin] [--autorizar-push <quem>] [--sem-push] [--dry-run]
397
402
 
398
403
  board [--all] [--sem-remoto] Visao unica das threads (todos os perfis com --all); com a
@@ -467,7 +472,8 @@ Uso: ork [--projeto <nome|caminho>] <comando> [argumentos]
467
472
  network roadmap [--projeto P] [--json] Roadmap, reservas e threads de cada maquina de cada projeto, de qualquer diretorio:
468
473
  [--sem-remoto] fonte e hora de cada parte, lacuna tipada no que nao leu. P = caminho do clone,
469
474
  github:dono/repo, gitlab:grupo/repo ou nome conhecido; sem clone, le a forja (RM-054)
470
- docs verificar [--json] Documentacao de produto e roadmap contra o codigo e o git
475
+ docs verificar [--json] [--pr] Documentacao de produto e roadmap contra o codigo e o git; no PR (--pr),
476
+ o merge de outra thread e o indice que divergem da main so avisam
471
477
  (padrao do dono: frontmatter, leitura, paridade; sai != 0 com erro)
472
478
  docs sincronizar [--escrever] Fatos do ledger e do git para o roadmap (merge, fase) e indices;
473
479
  sem --escrever so mostra; nunca muda status por passagem de tempo
@@ -725,14 +731,20 @@ function comandoThread(args) {
725
731
  console.log((0, thread_1.resumoDaThread)(thread));
726
732
  console.log('');
727
733
  console.log(` slug em 3 partes: ${(0, phase_1.descreverSlug)(thread.slug)}`);
734
+ const avisoSemBase = (0, thread_1.avisoDeThreadSemBase)(thread, gravada);
728
735
  if (gravada) {
729
736
  console.log(` estado: .orkastery/threads/${thread.id}/thread.json`);
730
737
  // Bloco B6: a origem da thread e as policies do projeto vao para a memoria
731
738
  // semantica quando ela esta ligada. Em regime files nada muda nesta saida.
732
739
  relatarPublicacao((0, memoria_1.publicar)(carregado, thread.id));
733
- console.log('');
734
- console.log(`Proximo passo: ork phase run ${thread.id} ${thread.faseAtual} --prompt "<pedido>"`);
740
+ // Thread sem base nao tem fase para rodar: o proximo passo e o do aviso.
741
+ if (!avisoSemBase) {
742
+ console.log('');
743
+ console.log(`Proximo passo: ork phase run ${thread.id} ${thread.faseAtual} --prompt "<pedido>"`);
744
+ }
735
745
  }
746
+ if (avisoSemBase)
747
+ console.error(avisoSemBase);
736
748
  return 0;
737
749
  }
738
750
  if (sub === 'list' || sub === undefined) {
@@ -1534,7 +1546,8 @@ function comandoVerify(args) {
1534
1546
  console.log(` ${c.nome.padEnd(10)} ${c.ok ? 'passava' : `ja falhava (codigo ${c.code})`} ${c.comando}`);
1535
1547
  }
1536
1548
  if (b.comandos.length === 0) {
1537
- console.log(' (nenhum comando em verify: no manifesto; sem baseline nao ha como separar regressao)');
1549
+ // Fatia 2 do ensaio da 0.5.0 (R5): a baseline foi gravada; o que falta e comando, nao baseline.
1550
+ console.log(' (nenhum comando em verify: no manifesto: a baseline guarda so o commit, e o verify nao tem como separar regressao de divida)');
1538
1551
  }
1539
1552
  return 0;
1540
1553
  }
@@ -1952,24 +1965,33 @@ function comandoShip(args) {
1952
1965
  // RM-037 (defeito 5): PR mesclado em repositorio externo declarado em ci.external_repositories.
1953
1966
  const repo = texto(args.opcoes.repo), numeroDoPr = texto(args.opcoes.pr);
1954
1967
  if ((!alvo && args.opcoes.todas !== true) || (!!repo !== !!numeroDoPr) || (repo && !alvo)) {
1955
- console.error('uso: ork ship registrar-pr <thread-id> [--repo <dono/nome> --pr <n>] | --todas [--remoto R] [--json]');
1968
+ console.error('uso: ork ship registrar-pr <thread-id> [--repo <dono/nome> --pr <n>] | --todas [--remoto R] [--json] [--dry-run]');
1956
1969
  return 2;
1957
1970
  }
1958
- const r = alvo && repo ? [(0, entrega_pr_1.registrarEntregaExternaPorPr)(carregado, alvo, { repositorio: repo, pr: Number(numeroDoPr) })]
1959
- : alvo ? [(0, entrega_pr_1.registrarEntregaPorPr)(carregado, alvo, { remoto })] : (0, entrega_pr_1.registrarEntregasPorPr)(carregado, { remoto });
1971
+ // RM-037 (fatia 3, defeito 6): o `--dry-run` era ignorado, e o ensaio gravava o ship_done de verdade.
1972
+ const dryRun = args.opcoes['dry-run'] === true;
1973
+ const r = alvo && repo ? [(0, entrega_pr_1.registrarEntregaExternaPorPr)(carregado, alvo, { repositorio: repo, pr: Number(numeroDoPr), dryRun })]
1974
+ : alvo ? [(0, entrega_pr_1.registrarEntregaPorPr)(carregado, alvo, { remoto, dryRun })] : (0, entrega_pr_1.registrarEntregasPorPr)(carregado, { remoto, dryRun });
1960
1975
  if (args.opcoes.json === true) {
1961
1976
  console.log(JSON.stringify(r, null, 2));
1962
1977
  return r.some((x) => x.acao === 'recusada') ? 1 : 0;
1963
1978
  }
1979
+ if (dryRun)
1980
+ console.log('Ensaio (--dry-run): nada foi gravado.');
1964
1981
  if (r.length === 0)
1965
1982
  console.log('Nenhuma thread aberta com merge ship(<thread>) na base.');
1966
1983
  for (const x of r)
1967
1984
  console.log(` ${x.thread.padEnd(20)} ${x.acao.padEnd(13)} ${x.motivo}`);
1968
1985
  const registradas = r.filter((x) => x.acao === 'registrou').length;
1986
+ const registrariam = r.filter((x) => x.acao === 'registraria').length;
1969
1987
  if (registradas) {
1970
1988
  console.log('');
1971
1989
  console.log(`${registradas} entrega(s) registrada(s). Fechar pelo MASTER: ork master --aceitar-omissao (a nota humana sobrescreve).`);
1972
1990
  }
1991
+ if (registrariam) {
1992
+ console.log('');
1993
+ console.log(`${registrariam} entrega(s) seria(m) registrada(s). Para gravar, rode o mesmo comando sem --dry-run.`);
1994
+ }
1973
1995
  return r.some((x) => x.acao === 'recusada') ? 1 : 0;
1974
1996
  }
1975
1997
  const id = args.posicionais[1];
@@ -2829,7 +2851,8 @@ function comandoDocs(args) {
2829
2851
  const raiz = carregado?.raiz ?? (0, manifest_1.diretorioDoProjeto)();
2830
2852
  const baseBranch = carregado?.manifesto.worktree?.base_branch ?? 'main';
2831
2853
  if (sub === 'verificar') {
2832
- const { docs, achados } = (0, docs_1.verificarDocs)(raiz, { baseBranch, ajudaDoCli: AJUDA });
2854
+ // RM-037 (fatia 3, GO-FIX 2): o CI passa --pr no pull_request; no push da main as duas regras novas reprovam.
2855
+ const { docs, achados } = (0, docs_1.verificarDocs)(raiz, { baseBranch, ajudaDoCli: AJUDA, pr: args.opcoes.pr === true });
2833
2856
  if (args.opcoes.json === true) {
2834
2857
  console.log(JSON.stringify({ paginas: docs.length, erros: achados.filter((a) => a.gravidade === 'erro').length,
2835
2858
  achados }, null, 2));
@@ -2881,7 +2904,7 @@ function comandoDocs(args) {
2881
2904
  'Proximo passo: copie docs/produto/_modelo-feature.md e docs/roadmap/_modelo-item.md, e rode ork docs verificar'].join('\n'));
2882
2905
  return 0;
2883
2906
  }
2884
- console.error(`uso: ork docs verificar [--json] | sincronizar [--escrever] [--so RM-NNN] [--todos] | init`);
2907
+ console.error(`uso: ork docs verificar [--json] [--pr] | sincronizar [--escrever] [--so RM-NNN] [--todos] | init`);
2885
2908
  return 2;
2886
2909
  }
2887
2910
  function comandoPrompt(args) {
@@ -3901,6 +3924,9 @@ function main(argvBruto) {
3901
3924
  console.log(` gerenciador ${r.deteccao.gerenciador}`);
3902
3925
  console.log(` verify ${Object.entries(r.deteccao.verify).map(([k, v]) => `${k}="${v}"`).join(', ') || '(nenhum script detectado)'}`);
3903
3926
  console.log(` AGENTS.md ${agents.estado}: ${agents.caminho}`);
3927
+ // Fatia 2 do ensaio da 0.5.0 (P3): o estado fica fora do git por um `.gitignore` proprio.
3928
+ if (r.estadoIgnorado)
3929
+ console.log(` estado ${manifest_1.DIR_ESTADO}/ fora do git (${manifest_1.DIR_ESTADO}/.gitignore com *; o seu .gitignore fica como está)`);
3904
3930
  console.log('');
3905
3931
  console.log(init_2.PROXIMO_PASSO_INIT);
3906
3932
  return 0;
@@ -3976,7 +4002,9 @@ function main(argvBruto) {
3976
4002
  // Preferência inválida vale o padrão e faz o adapter install pular o pacote: a consulta avisa.
3977
4003
  const avisos = manifesto.avisos.filter(a => a.startsWith('experiencia.config.invalid'));
3978
4004
  console.log(args.opcoes.json ? JSON.stringify({ ...p, avisos }, null, 2) :
3979
- `Experiência ${p.experience ? 'ativa' : 'desativada'}: ${p.language}, ${p.timezone}, profundidade ${p.depth}.\nSkill: ${p.skill}\nOrigens: ${JSON.stringify(p.origem)}` +
4005
+ `Experiência ${p.experience ? 'ativa' : 'desativada'}: ${p.language}, ${p.timezone}, profundidade ${p.depth}.\nSkill: ${p.skill}\n` +
4006
+ // Fatia 2 do ensaio da 0.5.0 (R2): as origens em texto, e nao o JSON cru.
4007
+ `Origens: ${Object.entries(p.origem).map(([chave, origem]) => `${chave} ${origem}`).join(', ')}` +
3980
4008
  avisos.map(a => `\nAviso: ${a}; o adapter install pula o pacote até ork onboarding set maestro corrigir.`).join(''));
3981
4009
  return 0;
3982
4010
  }
package/dist/init.js CHANGED
@@ -68,7 +68,12 @@ function nomeDetectado(dirInicial) {
68
68
  : path.basename(raizDoRepo(dirInicial));
69
69
  return base.replace(/-(novo|new|old|repo|main)$/i, '').toLowerCase();
70
70
  }
71
- /** Branch base do repositorio: origin/HEAD, senao main, senao master, senao a atual. */
71
+ /**
72
+ * Branch base do repositorio: origin/HEAD, senao main, senao master, senao a do HEAD.
73
+ * A do HEAD vem de `symbolic-ref`, que responde tambem no repositorio ainda sem commit (ensaio
74
+ * da 0.5.0: o `git init` sem `init.defaultBranch` nasce em `master`, e o `rev-parse` falhava e
75
+ * caia em `main`). HEAD destacado nao e branch: vale `main`.
76
+ */
72
77
  function baseBranchDetectada(raiz) {
73
78
  const origem = (0, util_1.exec)('git', ['symbolic-ref', '--quiet', 'refs/remotes/origin/HEAD'], raiz);
74
79
  if (origem.ok && origem.stdout.trim()) {
@@ -79,8 +84,7 @@ function baseBranchDetectada(raiz) {
79
84
  return candidata;
80
85
  }
81
86
  }
82
- const atual = (0, util_1.exec)('git', ['rev-parse', '--abbrev-ref', 'HEAD'], raiz);
83
- return atual.ok ? atual.stdout.trim() : 'main';
87
+ return (0, util_1.branchDoHead)(raiz) ?? 'main';
84
88
  }
85
89
  function gerenciadorDetectado(dir) {
86
90
  if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml')))
@@ -264,6 +268,8 @@ function init(dirInicial, opcoes = {}) {
264
268
  return { caminho, criado: false, deteccao };
265
269
  }
266
270
  (0, util_1.gravar)(caminho, manifestoYaml(deteccao));
267
- fs.mkdirSync(path.join(deteccao.raiz, manifest_1.DIR_ESTADO, 'threads'), { recursive: true });
268
- return { caminho, criado: true, deteccao };
271
+ const estado = path.join(deteccao.raiz, manifest_1.DIR_ESTADO);
272
+ fs.mkdirSync(path.join(estado, 'threads'), { recursive: true });
273
+ // Fatia 2 do ensaio da 0.5.0 (P3): o estado e da maquina; fica fora do git sem mexer no `.gitignore` do usuario.
274
+ return { caminho, criado: true, deteccao, estadoIgnorado: (0, util_1.ignorarPastaNoGit)(estado, deteccao.raiz) };
269
275
  }
@@ -14,4 +14,6 @@ exports.TESTES_DE_INTEGRACAO_LOCAL = new Set([
14
14
  'mcp-git.test.js', 'mcp-server.test.js', 'mcp-ship.test.js', 'mcp-verify.test.js',
15
15
  'memory-native-preparation.test.js', 'memory-native-schema.test.js', 'memory-prospective.test.js',
16
16
  'memory-publication-profile.test.js', 'native-fixture.test.js', 'orkmind-transport.test.js', 'verify-sandbox.test.js',
17
+ // RM-037 (fatia 3): o worker do ork_git_commit e o sandbox do verify de verdade, como no mcp-git.test.js.
18
+ 'rm037-fatia3-hard-link-mcp-git.test.js', 'rm037-fatia3-lease-mcp-git.test.js',
17
19
  ]);