@orkastery/cli 0.4.2 → 0.5.0
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/adapters/README.md +11 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +3 -1
- package/adapters/claude-code/agents/ork-check.md +1 -1
- package/adapters/claude-code/agents/ork-go.md +2 -2
- package/adapters/claude-code/agents/ork-goal.md +1 -1
- package/adapters/claude-code/agents/ork-master.md +1 -1
- package/adapters/claude-code/agents/ork-plan.md +1 -1
- package/adapters/claude-code/agents/ork-ship.md +1 -1
- package/adapters/claude-code/commands/master.md +11 -8
- package/adapters/claude-code/commands/ork.md +8 -0
- package/adapters/claude-code/commands/ship.md +2 -2
- package/adapters/codex/skills/ork/SKILL.md +12 -1
- package/adapters/hermes/README.md +3 -0
- package/adapters/hermes/bin/ork-abrir-thread.sh +17 -2
- package/adapters/hermes/bin/ork-brain.sh +3 -0
- package/adapters/hermes/bin/ork-maestro.sh +4 -1
- package/adapters/hermes/bin/ork-network-roadmap.sh +11 -0
- package/adapters/hermes/bin/ork-roadmap-status.sh +9 -0
- package/adapters/hermes/hermes.plugin.json +2 -0
- package/adapters/hermes/hitl-ingress/__init__.py +36 -3
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +19 -20
- package/adapters/openclaw/README.md +34 -3
- package/adapters/openclaw/dist/hitl-ingress.js +37 -3
- package/adapters/openclaw/dist/index.js +92 -39
- package/adapters/openclaw/openclaw.plugin.json +10 -3
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +32 -3
- package/adapters/openclaw/src/index.ts +108 -41
- package/assets/docs/padroes/documentacao-de-produto.md +2 -2
- package/assets/docs/padroes/roadmap-de-produto.md +1 -1
- package/assets/docs/produto/_modelo-feature.md +2 -0
- package/assets/orkmind_bridge.py +214 -1
- package/dist/adapters/claude-bg.js +88 -9
- package/dist/adapters/codex-events.js +3 -1
- package/dist/board.js +74 -0
- package/dist/branch-de-estado.js +5 -4
- package/dist/busca-semantica.js +161 -0
- package/dist/ci.js +141 -10
- package/dist/company-brain-cli.js +27 -2
- package/dist/company-brain-context.js +132 -0
- package/dist/company-brain-dossie.js +376 -0
- package/dist/company-brain-mcp.js +4 -1
- package/dist/conducao.js +117 -31
- package/dist/decisao-autonoma.js +42 -0
- package/dist/docs.js +64 -22
- package/dist/doctor.js +33 -0
- package/dist/entrega-pr.js +109 -5
- package/dist/experiencia-instalacao.js +256 -0
- package/dist/experiencia.js +72 -0
- package/dist/fabrica-estado.js +43 -10
- package/dist/fechamento.js +105 -0
- package/dist/fix.js +1 -1
- package/dist/forja.js +435 -0
- package/dist/gates.js +10 -1
- package/dist/hitl-classificacao.js +11 -1
- package/dist/hitl-contract.js +50 -7
- package/dist/hitl-curto.js +158 -0
- package/dist/hitl-gates.js +67 -1
- package/dist/hitl-lote.js +30 -15
- package/dist/hitl-presentation.js +10 -7
- package/dist/hitl-resumo.js +33 -12
- package/dist/hitl-texto-livre.js +150 -0
- package/dist/hosts.js +86 -1
- package/dist/index.js +605 -41
- package/dist/indice-vetorial.js +317 -0
- package/dist/init.js +13 -0
- package/dist/integracoes-locais.js +1 -1
- package/dist/intelligence-benchmark-contract.js +570 -0
- package/dist/intelligence-graph-cli.js +430 -0
- package/dist/intelligence-graph-contract.js +577 -0
- package/dist/intelligence-graph-extract-md.js +469 -0
- package/dist/intelligence-graph-extract-ts.js +810 -0
- package/dist/intelligence-graph-extract.js +369 -0
- package/dist/intelligence-graph-index.js +512 -0
- package/dist/intelligence-graph-parsers.js +327 -0
- package/dist/intelligence-graph-query.js +344 -0
- package/dist/intelligence-graph-repo.js +187 -0
- package/dist/leases.js +84 -0
- package/dist/ledger.js +14 -0
- package/dist/maestro-cli.js +10 -1
- package/dist/maestro-contract.js +5 -1
- package/dist/maestro-discovery.js +16 -2
- package/dist/maestro-snapshot.js +6 -2
- package/dist/manifest.js +142 -5
- package/dist/master-batch.js +3 -2
- package/dist/master-digest.js +2 -2
- package/dist/master-nota.js +203 -0
- package/dist/master.js +4 -0
- package/dist/mcp-experiencia.js +164 -0
- package/dist/mcp-git.js +36 -10
- package/dist/mcp-install.js +3 -1
- package/dist/mcp-maestro.js +3 -2
- package/dist/mcp-server.js +84 -5
- package/dist/memoria.js +147 -1
- package/dist/network-roadmap.js +907 -0
- package/dist/ocupacao.js +38 -2
- package/dist/onboarding.js +113 -7
- package/dist/orkmind.js +165 -9
- package/dist/phase.js +166 -13
- package/dist/policies.js +2 -0
- package/dist/projeto-alvo.js +551 -0
- package/dist/prompts.js +1 -1
- package/dist/pulse-consentimento.js +4 -2
- package/dist/pulse-delivery.js +5 -0
- package/dist/pulse-resposta.js +674 -49
- package/dist/pulse.js +21 -0
- package/dist/ratelimit.js +3 -2
- package/dist/retry.js +230 -9
- package/dist/roadmap-reservas.js +262 -20
- package/dist/roadmap-status.js +213 -0
- package/dist/runtime-ambiente.js +12 -1
- package/dist/session-watcher-claude.js +26 -0
- package/dist/sessoes.js +49 -15
- package/dist/thread-close.js +3 -0
- package/dist/verify.js +5 -4
- package/dist/worktree.js +77 -0
- package/eval/casos/orchestration-experience-pt-br.json +48 -0
- package/eval/casos/orchestration-experience.json +48 -0
- package/package.json +1 -1
- package/schemas/code-artifact-graph.v1.schema.json +581 -0
- package/schemas/graph-benchmark.v1.schema.json +2240 -0
- package/schemas/maestro-snapshot.schema.json +23 -0
- package/skills/README.md +7 -5
- package/skills/core/onboarding/SKILL.md +7 -0
- package/skills/core/orchestration-experience/SKILL.md +113 -0
- package/skills/core/orchestration-experience-pt-br/SKILL.md +112 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/go-implementation/SKILL.md +2 -0
|
@@ -158,6 +158,20 @@ function classificarSessaoClaude(e) {
|
|
|
158
158
|
: { terminal: true, classificacao: 'fase_concluida', motivo: null, fonte: `${sinal}; ${prova.fonte}`, conclusaoNativa, stop };
|
|
159
159
|
return { ...c, dependeDoStop: true };
|
|
160
160
|
};
|
|
161
|
+
// RM-037 (defeitosdeco D-1): turno encerrado pelo Stop e sessão viva em `blocked` é o Claude Code
|
|
162
|
+
// dizendo que o texto final pediu resposta. Nunca conclui direto, e a pausa humana abre sempre
|
|
163
|
+
// (`human.pending`): GO-FIX (R6 do CHECK), sem a prova o motivo também é o humano, porque um
|
|
164
|
+
// `artifact.missing` automático abriria correção sobre uma sessão viva que espera resposta.
|
|
165
|
+
const esperaHumana = () => {
|
|
166
|
+
const sinal = 'Stop correlacionado e sessão viva à espera humana (blocked)';
|
|
167
|
+
const prova = e.prova();
|
|
168
|
+
const c = !prova.ok
|
|
169
|
+
? { ...bloqueio(`${sinal}; sem prova do ork: ${prova.fonte}; o humano decide`, 'human.pending'),
|
|
170
|
+
diagnostico: `a sessão espera resposta humana (blocked) e a fase ainda não tem a prova do ork: ${prova.fonte}` }
|
|
171
|
+
: { ...bloqueio(`${sinal}; ${prova.fonte}; o humano decide`, 'human.pending'),
|
|
172
|
+
diagnostico: 'a fase tem a prova do ork e a sessão espera resposta humana (blocked): o humano decide' };
|
|
173
|
+
return { ...c, dependeDoStop: true };
|
|
174
|
+
};
|
|
161
175
|
const venceu = (desde) => agora - desde >= e.limiteMs;
|
|
162
176
|
// Sem prova para concluir nem para bloquear: `runtime.unavailable` reexecutaria o mesmo prompt
|
|
163
177
|
// sobre uma fase que pode ter terminado. O observador encerra sem gate e o radar de liveness
|
|
@@ -183,6 +197,8 @@ function classificarSessaoClaude(e) {
|
|
|
183
197
|
delete cursor.doneDesde;
|
|
184
198
|
if (estado !== 'working' && estado !== 'blocked')
|
|
185
199
|
delete cursor.mortoDesde;
|
|
200
|
+
if (estado !== 'blocked')
|
|
201
|
+
delete cursor.bloqueadoDesde;
|
|
186
202
|
if (['done', 'failed', 'stopped', 'working', 'blocked'].includes(estado ?? ''))
|
|
187
203
|
delete cursor.desconhecidoDesde;
|
|
188
204
|
switch (estado) {
|
|
@@ -220,6 +236,16 @@ function classificarSessaoClaude(e) {
|
|
|
220
236
|
return bloqueio(`processo da sessão morreu sem terminal nativo nem Stop correlacionado (estado ${estado})`);
|
|
221
237
|
}
|
|
222
238
|
delete cursor.mortoDesde;
|
|
239
|
+
// D-1: a segunda leitura, com pelo menos um intervalo do observador, separa o `blocked` estável
|
|
240
|
+
// de um instante de transição logo depois do Stop. `status` ocupado ainda é trabalho.
|
|
241
|
+
const ocupado = ['busy', 'running', 'working'].includes(r.status ?? '');
|
|
242
|
+
if (estado === 'blocked' && stop && !bloqueioPendente(e.eventos, e.sessao) && !ocupado) {
|
|
243
|
+
cursor.bloqueadoDesde ??= agora;
|
|
244
|
+
if (agora - cursor.bloqueadoDesde < exports.INTERVALO_WATCH_CLAUDE_MS)
|
|
245
|
+
return espera('turno encerrado pelo Stop com a sessão à espera humana (blocked); aguardando a segunda observação');
|
|
246
|
+
return esperaHumana();
|
|
247
|
+
}
|
|
248
|
+
delete cursor.bloqueadoDesde;
|
|
223
249
|
return espera(estado === 'blocked' ? 'sessão bloqueada à espera humana' : 'sessão trabalhando');
|
|
224
250
|
}
|
|
225
251
|
default:
|
package/dist/sessoes.js
CHANGED
|
@@ -46,6 +46,7 @@ exports.pararSessao = pararSessao;
|
|
|
46
46
|
exports.comandoDeAttach = comandoDeAttach;
|
|
47
47
|
const adapter = __importStar(require("./adapters/claude-bg"));
|
|
48
48
|
const sessoes_inventario_1 = require("./sessoes-inventario");
|
|
49
|
+
const runtime_profiles_1 = require("./runtime-profiles");
|
|
49
50
|
const util_1 = require("./util");
|
|
50
51
|
function textoDoInventario(r) {
|
|
51
52
|
const linhas = [
|
|
@@ -63,23 +64,56 @@ function textoDoInventario(r) {
|
|
|
63
64
|
function tabelaDeSessoes(raiz, todas = false) {
|
|
64
65
|
return textoDoInventario((0, sessoes_inventario_1.inventariarSessoes)(raiz, { todas }));
|
|
65
66
|
}
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
/**
|
|
68
|
+
* RM-037 (defeitosdeco D-2): a sessao pelo id curto, id completo ou nome, procurada no ambiente do
|
|
69
|
+
* processo e em cada perfil claude-bg do projeto (inclusive desativado, que ainda pode ter sessao
|
|
70
|
+
* viva). So uma conta pode responder; duas viram recusa, nenhuma mantem a mensagem de antes.
|
|
71
|
+
*/
|
|
72
|
+
function localizarSessao(chave, raiz) {
|
|
73
|
+
let perfis = [];
|
|
74
|
+
const falhas = [];
|
|
75
|
+
if (raiz) {
|
|
76
|
+
try {
|
|
77
|
+
perfis = (0, runtime_profiles_1.lerPerfis)(raiz).perfis.filter(p => p.runtime === 'claude-bg').map(runtime_profiles_1.perfilDeDespacho);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
falhas.push(`perfis: ${e.message}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const r = adapter.acharSessaoNasContas(chave, perfis);
|
|
84
|
+
falhas.push(...r.falhas);
|
|
85
|
+
if (r.achadas.length === 1)
|
|
86
|
+
return { achada: r.achadas[0] };
|
|
87
|
+
if (r.achadas.length > 1) {
|
|
88
|
+
const contas = r.achadas.map(a => `${a.perfil?.id ?? 'processo'} (${a.sessao.sessionId})`).join(', ');
|
|
89
|
+
return { texto: `sessao "${chave}" encontrada em mais de uma conta: ${contas}; use o id completo`, codigo: 1 };
|
|
90
|
+
}
|
|
91
|
+
return { texto: `sessao "${chave}" nao encontrada no runtime` + (falhas.length ? `; contas sem resposta: ${falhas.join('; ')}` : ''),
|
|
92
|
+
codigo: 1 };
|
|
93
|
+
}
|
|
94
|
+
/** Logs de uma sessao pelo id curto, id completo ou nome, lidos na conta onde ela esta. */
|
|
95
|
+
function logsDaSessao(chave, linhas, raiz) {
|
|
96
|
+
const l = localizarSessao(chave, raiz);
|
|
97
|
+
if (!('achada' in l))
|
|
98
|
+
return l;
|
|
99
|
+
const { sessao, ambiente } = l.achada;
|
|
100
|
+
const r = adapter.logsDaSessao(sessao.id ?? sessao.sessionId.slice(0, 8), linhas, ambiente);
|
|
69
101
|
return { texto: r.texto, codigo: r.ok ? 0 : 1 };
|
|
70
102
|
}
|
|
71
|
-
/** Para uma sessao pelo id curto, id completo ou nome. */
|
|
72
|
-
function pararSessao(chave) {
|
|
73
|
-
const
|
|
74
|
-
if (!
|
|
75
|
-
return
|
|
76
|
-
const
|
|
77
|
-
|
|
103
|
+
/** Para uma sessao pelo id curto, id completo ou nome, com o `CLAUDE_CONFIG_DIR` da conta dela. */
|
|
104
|
+
function pararSessao(chave, raiz) {
|
|
105
|
+
const l = localizarSessao(chave, raiz);
|
|
106
|
+
if (!('achada' in l))
|
|
107
|
+
return l;
|
|
108
|
+
const { sessao, perfil, ambiente } = l.achada;
|
|
109
|
+
const r = adapter.pararAchada(sessao, ambiente);
|
|
110
|
+
return { texto: r.texto || `sessao ${sessao.sessionId} parada${perfil ? ` (perfil ${perfil.id})` : ''}`, codigo: r.ok ? 0 : 1 };
|
|
78
111
|
}
|
|
79
112
|
/** Comando de attach (precisa de TTY, entao o CLI imprime em vez de executar). */
|
|
80
|
-
function comandoDeAttach(chave) {
|
|
81
|
-
const
|
|
82
|
-
if (!
|
|
83
|
-
return
|
|
84
|
-
|
|
113
|
+
function comandoDeAttach(chave, raiz) {
|
|
114
|
+
const l = localizarSessao(chave, raiz);
|
|
115
|
+
if (!('achada' in l))
|
|
116
|
+
return l;
|
|
117
|
+
const { sessao, perfil, configDir } = l.achada;
|
|
118
|
+
return { texto: adapter.comandoAttach(sessao.sessionId, perfil ? configDir : null), codigo: 0 };
|
|
85
119
|
}
|
package/dist/thread-close.js
CHANGED
|
@@ -47,6 +47,7 @@ const ledger_1 = require("./ledger");
|
|
|
47
47
|
const estado_thread_1 = require("./estado-thread");
|
|
48
48
|
const util_1 = require("./util");
|
|
49
49
|
const fabrica_publicar_1 = require("./fabrica-publicar");
|
|
50
|
+
const fechamento_1 = require("./fechamento");
|
|
50
51
|
function validarArtefato(raiz, arquivo, sha256) {
|
|
51
52
|
if (!/^[a-f0-9]{64}$/.test(sha256))
|
|
52
53
|
throw new Error('sha256 inválido');
|
|
@@ -111,5 +112,7 @@ function fecharAdministrativamente(raiz, id, opcoes) {
|
|
|
111
112
|
t.status = 'fechada';
|
|
112
113
|
(0, thread_1.gravarThread)(raiz, t);
|
|
113
114
|
(0, fabrica_publicar_1.publicarEmSegundoPlano)(raiz);
|
|
115
|
+
// RM-037 (rm037noite): a thread fechada solta o que segurava, com registro no ledger dela.
|
|
116
|
+
(0, fechamento_1.liberarAoFechar)(raiz, id);
|
|
114
117
|
return t;
|
|
115
118
|
}
|
package/dist/verify.js
CHANGED
|
@@ -191,7 +191,7 @@ function pedidoDoVerify(carregado, threadId, operacao, comandos, conducao) {
|
|
|
191
191
|
canal: conducao.canal ?? (0, conducao_1.canalDoProcesso)(),
|
|
192
192
|
correlacao: conducao.correlacao ?? null,
|
|
193
193
|
operacao,
|
|
194
|
-
identidade: conducao.identidade ?? (0, conducao_1.identidadeDoAmbiente)(threadId),
|
|
194
|
+
identidade: conducao.identidade ?? (0, conducao_1.identidadeDoAmbiente)(threadId, process.env, carregado.raiz),
|
|
195
195
|
prazoMs: (0, conducao_1.prazoDaVerificacao)(carregado.manifesto.verify.timeout_ms ?? exports.TIMEOUT_VERIFY_MS, comandos),
|
|
196
196
|
esperarMs: conducao.esperarMs,
|
|
197
197
|
};
|
|
@@ -204,11 +204,11 @@ function executorSobConducao(base, manifesto, conducao) {
|
|
|
204
204
|
};
|
|
205
205
|
}
|
|
206
206
|
/** `ork verify --baseline`: grava o estado do mundo ANTES do GO. */
|
|
207
|
-
function gravarBaseline(carregado, threadId, executor = executar, conducao = {}) {
|
|
207
|
+
function gravarBaseline(carregado, threadId, executor = executar, conducao = {}, origem = 'cli') {
|
|
208
208
|
const pedido = pedidoDoVerify(carregado, threadId, 'baseline', comandosDoManifesto(carregado.manifesto).length, conducao);
|
|
209
|
-
return (0, conducao_1.comConducao)(carregado.raiz, threadId, pedido, (tomada) => gravarBaselineSobConducao(carregado, threadId, executorSobConducao(executor, carregado.manifesto, tomada)));
|
|
209
|
+
return (0, conducao_1.comConducao)(carregado.raiz, threadId, pedido, (tomada) => gravarBaselineSobConducao(carregado, threadId, executorSobConducao(executor, carregado.manifesto, tomada), origem));
|
|
210
210
|
}
|
|
211
|
-
function gravarBaselineSobConducao(carregado, threadId, executor) {
|
|
211
|
+
function gravarBaselineSobConducao(carregado, threadId, executor, origem) {
|
|
212
212
|
const { raiz, manifesto } = carregado;
|
|
213
213
|
const thread = (0, thread_1.lerThread)(raiz, threadId);
|
|
214
214
|
const cwd = cwdDaThread(raiz, thread);
|
|
@@ -221,6 +221,7 @@ function gravarBaselineSobConducao(carregado, threadId, executor) {
|
|
|
221
221
|
cwd,
|
|
222
222
|
comandos: comandos.map((c) => ({ nome: c.nome, comando: c.comando, ok: c.ok, code: c.code })),
|
|
223
223
|
fonte: 'execucao real no HEAD, nao relatorio de fase',
|
|
224
|
+
origem,
|
|
224
225
|
});
|
|
225
226
|
return baseline;
|
|
226
227
|
}
|
package/dist/worktree.js
CHANGED
|
@@ -52,6 +52,7 @@ exports.worktreesDoGit = worktreesDoGit;
|
|
|
52
52
|
exports.registradaNoGit = registradaNoGit;
|
|
53
53
|
exports.arvoreLimpa = arvoreLimpa;
|
|
54
54
|
exports.garantirWorktree = garantirWorktree;
|
|
55
|
+
exports.historiaPropria = historiaPropria;
|
|
55
56
|
exports.sincronizarWorktree = sincronizarWorktree;
|
|
56
57
|
exports.auditarWorktree = auditarWorktree;
|
|
57
58
|
exports.textoDoAudit = textoDoAudit;
|
|
@@ -189,6 +190,34 @@ function garantirWorktree(carregado, id) {
|
|
|
189
190
|
correcao: '',
|
|
190
191
|
};
|
|
191
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* RM-037 (defeitosdeco D-5): o que a branch tem de proprio. Bases conhecidas da thread sao o
|
|
195
|
+
* `base.commit` carimbado na criacao e cada `shaBase` que um sync ja incorporou (lidos do ledger);
|
|
196
|
+
* commit que o git nao tem mais nao entra. `proprios` conta o que o HEAD tem fora delas e da base
|
|
197
|
+
* atual (`null` sem nenhuma base conhecida); `pontoDePartida` e a base conhecida mais nova que e
|
|
198
|
+
* ancestral do HEAD; `semAncestral` diz que HEAD e base atual nao tem historia em comum.
|
|
199
|
+
*/
|
|
200
|
+
function historiaPropria(raiz, thread, dir, shaBase) {
|
|
201
|
+
const git = (...args) => (0, util_1.exec)('git', args, dir);
|
|
202
|
+
const sincronizadas = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, thread.id))
|
|
203
|
+
.filter(e => e.tipo === ledger_1.TIPOS_DE_EVENTO.worktreeSincronizada && typeof e.shaBase === 'string' && e.shaBase !== '')
|
|
204
|
+
.map(e => String(e.shaBase));
|
|
205
|
+
// GO-FIX (R1): no ciclo `merge-branch`, `base.commit` e a ponta da branch que ja existia, com os
|
|
206
|
+
// commits proprios dela. Nao e base: vale so o ponto onde ela sai da base atual, quando existe.
|
|
207
|
+
const inicio = thread.base?.commit;
|
|
208
|
+
const valido = (sha) => typeof sha === 'string' && /^[a-f0-9]{40,64}$/.test(sha) &&
|
|
209
|
+
git('cat-file', '-e', `${sha}^{commit}`).ok;
|
|
210
|
+
const pontoDaCriacao = thread.variante !== 'merge-branch' ? inicio
|
|
211
|
+
: valido(inicio) ? (git('merge-base', inicio, shaBase).stdout.trim() || null) : null;
|
|
212
|
+
const conhecidas = [...new Set([pontoDaCriacao, ...sincronizadas])].filter(valido);
|
|
213
|
+
const semAncestral = git('merge-base', 'HEAD', shaBase).code === 1;
|
|
214
|
+
const pontoDePartida = [...conhecidas].reverse().find(sha => git('merge-base', '--is-ancestor', sha, 'HEAD').ok) ?? null;
|
|
215
|
+
if (!conhecidas.length)
|
|
216
|
+
return { proprios: null, pontoDePartida, semAncestral };
|
|
217
|
+
const contagem = git('rev-list', '--count', 'HEAD', '--not', ...conhecidas, shaBase);
|
|
218
|
+
const proprios = contagem.ok && /^\d+$/.test(contagem.stdout.trim()) ? Number(contagem.stdout.trim()) : null;
|
|
219
|
+
return { proprios, pontoDePartida, semAncestral };
|
|
220
|
+
}
|
|
192
221
|
/**
|
|
193
222
|
* Sincroniza a branch da thread com a base ATUAL (rebase), quando a base avancou.
|
|
194
223
|
*
|
|
@@ -287,6 +316,54 @@ function sincronizarWorktree(carregado, id, opcoes = {}) {
|
|
|
287
316
|
correcao: '',
|
|
288
317
|
};
|
|
289
318
|
}
|
|
319
|
+
// RM-037 (defeitosdeco D-5): depois do corte de 27/09 a base tem raiz nova. Branch sem commit
|
|
320
|
+
// proprio nao e rebasada: o rebase sem ancestral comum reaplicaria a historia antiga inteira. Ela
|
|
321
|
+
// e recriada no SHA da base com `reset --keep`, que aborta se houvesse mudanca local a perder (a
|
|
322
|
+
// arvore ja foi conferida limpa). Com commit proprio e sem ancestral comum, a branch fica como esta
|
|
323
|
+
// e a correcao exata reaplica so o que e dela.
|
|
324
|
+
const historia = historiaPropria(raiz, thread, dir, shaBase);
|
|
325
|
+
if (historia.proprios === 0) {
|
|
326
|
+
passos.push(`git reset --keep ${shaBase}`);
|
|
327
|
+
if (opcoes.dryRun) {
|
|
328
|
+
return { ...vazio, shaBase, shaAntes, shaDepois: shaAntes, ok: true, jaAtualizada: false, rebaseFeito: false, recriada: false,
|
|
329
|
+
motivo: null, detalhe: `a branch ${branch} nao tem commit proprio: o sync real a recriaria na base ${base} atual, sem rebase`,
|
|
330
|
+
correcao: '' };
|
|
331
|
+
}
|
|
332
|
+
let recriacao;
|
|
333
|
+
try {
|
|
334
|
+
recriacao = (0, estado_thread_1.comEstadoParaGit)(raiz, id, dir, () => (0, util_1.exec)('git', ['reset', '--keep', shaBase], dir));
|
|
335
|
+
}
|
|
336
|
+
catch (e) {
|
|
337
|
+
return { ...vazio, shaBase, shaAntes, ok: false, jaAtualizada: false, rebaseFeito: false,
|
|
338
|
+
motivo: 'tree.blocked', detalhe: e.message,
|
|
339
|
+
correcao: 'inspecione a cópia local e a fonte canônica preservadas antes de repetir o sync' };
|
|
340
|
+
}
|
|
341
|
+
const shaDepois = (0, util_1.exec)('git', ['rev-parse', 'HEAD'], dir).stdout.trim();
|
|
342
|
+
if (!recriacao.ok || shaDepois !== shaBase) {
|
|
343
|
+
return { ...vazio, shaBase, shaAntes, shaDepois, ok: false, jaAtualizada: false, rebaseFeito: false, motivo: 'tree.blocked',
|
|
344
|
+
detalhe: `a recriacao da branch ${branch} na base falhou: ${(recriacao.stderr || recriacao.stdout).trim().split('\n').slice(-2).join(' | ')}`,
|
|
345
|
+
correcao: `confira a worktree ${dir} e rode de novo: ork worktree sync ${id}` };
|
|
346
|
+
}
|
|
347
|
+
const detalhe = historia.semAncestral
|
|
348
|
+
? `branch sem commit proprio recriada a partir da base ${base} atual; a base foi reescrita e nao tinha historia em comum com ela`
|
|
349
|
+
: `branch sem commit proprio recriada a partir da base ${base} atual`;
|
|
350
|
+
(0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeSincronizada, { dir, branch, base, shaBase, shaAntes, shaDepois,
|
|
351
|
+
rebaseFeito: false, recriada: true, semAncestral: historia.semAncestral, detalhe });
|
|
352
|
+
return { ...vazio, shaBase, shaAntes, shaDepois, ok: true, jaAtualizada: false, rebaseFeito: false, recriada: true,
|
|
353
|
+
motivo: null, detalhe, correcao: '' };
|
|
354
|
+
}
|
|
355
|
+
if (historia.semAncestral) {
|
|
356
|
+
const onto = historia.pontoDePartida
|
|
357
|
+
? `git -C ${dir} rebase --onto ${shaBase} ${historia.pontoDePartida}`
|
|
358
|
+
: `git -C ${dir} rebase --onto ${shaBase} <commit onde a branch da thread comecou>`;
|
|
359
|
+
const detalhe = `a base ${base} foi reescrita e nao tem historia em comum com a branch ${branch}, que tem ` +
|
|
360
|
+
`${historia.proprios ?? 'um numero desconhecido de'} commit(s) proprio(s): o rebase reaplicaria a historia antiga inteira`;
|
|
361
|
+
if (!opcoes.dryRun)
|
|
362
|
+
(0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeSincronizada, { dir, branch, base, shaBase, shaAntes,
|
|
363
|
+
rebaseFeito: false, motivo: 'tree.blocked', semAncestral: true, detalhe });
|
|
364
|
+
return { ...vazio, shaBase, shaAntes, shaDepois: shaAntes, ok: false, jaAtualizada: false, rebaseFeito: false,
|
|
365
|
+
motivo: 'tree.blocked', detalhe, correcao: `reaplique so os commits da thread sobre a base nova: ${onto}` };
|
|
366
|
+
}
|
|
290
367
|
if (opcoes.dryRun) {
|
|
291
368
|
passos.push(`git rebase ${shaBase}`);
|
|
292
369
|
return {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "orchestration-experience-pt-br",
|
|
3
|
+
"casos": [
|
|
4
|
+
{
|
|
5
|
+
"id": "orchestration-experience-pt-br/conversa",
|
|
6
|
+
"tipo": "caminho-feliz",
|
|
7
|
+
"gravidade": "maior",
|
|
8
|
+
"cenario": "Instalação ativa: consultar preferências antes da conversa.",
|
|
9
|
+
"esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
|
|
10
|
+
"assercoes": [
|
|
11
|
+
{
|
|
12
|
+
"tipo": "contem",
|
|
13
|
+
"valor": "ork experiencia show --json",
|
|
14
|
+
"porque": "Âncora operacional: removê-la reprova a proteção estática."
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "orchestration-experience-pt-br/prova",
|
|
20
|
+
"tipo": "racionalizacao",
|
|
21
|
+
"gravidade": "maior",
|
|
22
|
+
"cenario": "Agente sugere aceitar silêncio como aprovação e dizer que o teste passou.",
|
|
23
|
+
"esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
|
|
24
|
+
"assercoes": [
|
|
25
|
+
{
|
|
26
|
+
"tipo": "contem",
|
|
27
|
+
"valor": "Silêncio não é aprovação humana",
|
|
28
|
+
"porque": "Âncora operacional: removê-la reprova a proteção estática."
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"racionalizacao": "É mais rápido declarar sucesso sem prova."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "orchestration-experience-pt-br/fronteira",
|
|
35
|
+
"tipo": "borda",
|
|
36
|
+
"gravidade": "maior",
|
|
37
|
+
"cenario": "Sessão filha tenta reservar item ou alterar sandbox por conta da skill.",
|
|
38
|
+
"esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
|
|
39
|
+
"assercoes": [
|
|
40
|
+
{
|
|
41
|
+
"tipo": "contem",
|
|
42
|
+
"valor": "Consultar não reserva",
|
|
43
|
+
"porque": "Âncora operacional: removê-la reprova a proteção estática."
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "orchestration-experience",
|
|
3
|
+
"casos": [
|
|
4
|
+
{
|
|
5
|
+
"id": "orchestration-experience/conversa",
|
|
6
|
+
"tipo": "caminho-feliz",
|
|
7
|
+
"gravidade": "maior",
|
|
8
|
+
"cenario": "Instalação ativa: consultar preferências antes da conversa.",
|
|
9
|
+
"esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
|
|
10
|
+
"assercoes": [
|
|
11
|
+
{
|
|
12
|
+
"tipo": "contem",
|
|
13
|
+
"valor": "ork experiencia show --json",
|
|
14
|
+
"porque": "Âncora operacional: removê-la reprova a proteção estática."
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "orchestration-experience/prova",
|
|
20
|
+
"tipo": "racionalizacao",
|
|
21
|
+
"gravidade": "maior",
|
|
22
|
+
"cenario": "Agente sugere aceitar silêncio como aprovação e dizer que o teste passou.",
|
|
23
|
+
"esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
|
|
24
|
+
"assercoes": [
|
|
25
|
+
{
|
|
26
|
+
"tipo": "contem",
|
|
27
|
+
"valor": "Silence is not human approval",
|
|
28
|
+
"porque": "Âncora operacional: removê-la reprova a proteção estática."
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"racionalizacao": "É mais rápido declarar sucesso sem prova."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "orchestration-experience/fronteira",
|
|
35
|
+
"tipo": "borda",
|
|
36
|
+
"gravidade": "maior",
|
|
37
|
+
"cenario": "Sessão filha tenta reservar item ou alterar sandbox por conta da skill.",
|
|
38
|
+
"esperado": "Usa dados efetivos e preserva autoridade, evidência e escopo do núcleo.",
|
|
39
|
+
"assercoes": [
|
|
40
|
+
{
|
|
41
|
+
"tipo": "contem",
|
|
42
|
+
"valor": "A query does not reserve",
|
|
43
|
+
"porque": "Âncora operacional: removê-la reprova a proteção estática."
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkastery/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A software factory of AI agents that proves its work: parallel threads, verified results, and short decisions only when they matter.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/orkastery/orkastery#readme",
|