@orkastery/cli 0.5.3 → 0.5.6
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/claude-code/README.md +158 -0
- package/adapters/claude-code/mods/autoridade.json +56 -0
- package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
- package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
- package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
- package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
- package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
- package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
- package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
- package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
- package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
- package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
- package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
- package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
- package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
- package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
- package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
- package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
- package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
- package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
- package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
- package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
- package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
- package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
- package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
- package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
- package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
- package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
- package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
- package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
- package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
- package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
- package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
- package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
- package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
- package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +1 -1
- package/adapters/openclaw/README.md +2 -1
- package/adapters/openclaw/openclaw.plugin.json +1 -1
- package/adapters/openclaw/package.json +1 -1
- package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
- package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
- package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
- package/assets/docs-en/produto/README.md +14 -0
- package/assets/docs-en/produto/_modelo-feature.md +62 -0
- package/assets/docs-en/roadmap/README.md +14 -0
- package/assets/docs-en/roadmap/_modelo-item.md +75 -0
- package/dist/adapters/claude-bg.js +77 -13
- package/dist/adapters/codex.js +10 -1
- package/dist/agents-md.js +24 -15
- package/dist/auditrun.js +17 -2
- package/dist/board.js +4 -3
- package/dist/branch-de-estado.js +23 -1
- package/dist/catalogo.js +33 -0
- package/dist/ci.js +13 -7
- package/dist/claims-conferir.js +342 -0
- package/dist/claims.js +3 -1
- package/dist/company-brain-client.js +36 -1
- package/dist/company-brain-journal.js +2 -1
- package/dist/company-brain-migration.js +36 -1
- package/dist/conducao-sentinela.js +388 -0
- package/dist/conducao-texto.js +12 -18
- package/dist/conducao.js +122 -30
- package/dist/conhecimento.js +490 -0
- package/dist/docs.js +22 -8
- package/dist/doctor-pulse-cron.js +182 -27
- package/dist/doctor-rede.js +18 -17
- package/dist/doctor.js +115 -111
- package/dist/entrega-pr.js +22 -21
- package/dist/escopo-escrita.js +10 -1
- package/dist/estado-thread.js +23 -1
- package/dist/experiencia-instalacao.js +45 -25
- package/dist/fabrica-batida.js +310 -0
- package/dist/fabrica-estado.js +38 -8
- package/dist/fabrica-publicar.js +3 -1
- package/dist/fila-pesada.js +444 -0
- package/dist/fix.js +3 -2
- package/dist/forja.js +1 -1
- package/dist/gates.js +3 -28
- package/dist/handoff.js +10 -6
- package/dist/hitl-local-receipt.js +2 -0
- package/dist/hitl-resumo.js +29 -3
- package/dist/hitl-tempo-parado.js +4 -4
- package/dist/hitl.js +29 -33
- package/dist/horario.js +14 -7
- package/dist/hosts.js +52 -1
- package/dist/impedimento.js +108 -14
- package/dist/index.js +623 -521
- package/dist/indice.js +7 -1
- package/dist/init.js +43 -47
- package/dist/instabilidade.js +144 -0
- package/dist/integracoes-locais.js +2 -0
- package/dist/intelligence-graph-cli.js +92 -21
- package/dist/intelligence-graph-contexto.js +56 -17
- package/dist/intelligence-graph-contract.js +2 -1
- package/dist/intelligence-graph-extract-md.js +56 -4
- package/dist/intelligence-graph-extract-ts.js +71 -3
- package/dist/intelligence-graph-query.js +66 -19
- package/dist/ledger.js +15 -1
- package/dist/liveness.js +6 -3
- package/dist/locale-ajuda.js +761 -0
- package/dist/locale-gerados.js +160 -0
- package/dist/locale-master.js +99 -0
- package/dist/locale-onboarding.js +92 -0
- package/dist/locale-phase.js +151 -0
- package/dist/locale-pulse.js +211 -0
- package/dist/locale-retry.js +385 -0
- package/dist/locale-roadmap.js +102 -0
- package/dist/locale-ship.js +494 -0
- package/dist/locale-thread.js +277 -0
- package/dist/locale-verify.js +125 -0
- package/dist/locale.js +714 -0
- package/dist/manifest.js +129 -3
- package/dist/maquina.js +23 -4
- package/dist/master-digest.js +6 -1
- package/dist/master-nota.js +4 -6
- package/dist/master.js +21 -24
- package/dist/mcp-artifacts.js +11 -2
- package/dist/mcp-git.js +23 -6
- package/dist/mcp-grafo.js +7 -4
- package/dist/mcp-server.js +8 -2
- package/dist/mcp-ship.js +3 -1
- package/dist/mcp-verify.js +6 -1
- package/dist/modos.js +3 -6
- package/dist/network-roadmap.js +5 -2
- package/dist/noctum-arco.js +911 -0
- package/dist/noctum-capacidade.js +141 -0
- package/dist/noctum-envelope.js +810 -0
- package/dist/noctum-execucao.js +304 -0
- package/dist/noctum-fila.js +280 -0
- package/dist/ocupacao.js +29 -2
- package/dist/onboarding.js +40 -21
- package/dist/orkmind.js +9 -2
- package/dist/orquestracao.js +13 -12
- package/dist/parado-no-condutor.js +34 -9
- package/dist/phase.js +94 -39
- package/dist/policies.js +4 -4
- package/dist/portfolio.js +4 -2
- package/dist/postura-local.js +234 -0
- package/dist/preflight.js +11 -10
- package/dist/procedencia.js +225 -0
- package/dist/projeto-alvo.js +127 -4
- package/dist/prompts.js +6 -2
- package/dist/pulse-delivery.js +13 -2
- package/dist/pulse.js +52 -19
- package/dist/ratelimit.js +4 -2
- package/dist/redacao-saida.js +63 -0
- package/dist/rede-status.js +3 -2
- package/dist/retry.js +232 -148
- package/dist/roadmap-reservas.js +20 -3
- package/dist/roadmap-status.js +129 -33
- package/dist/runtime-context.js +181 -3
- package/dist/runtimes.js +2 -1
- package/dist/session-events.js +7 -3
- package/dist/session-watcher-claude.js +7 -1
- package/dist/session-watcher.js +185 -33
- package/dist/sessoes-contas.js +1 -1
- package/dist/ship-publicar.js +800 -0
- package/dist/ship.js +84 -81
- package/dist/steal.js +77 -0
- package/dist/thread-close.js +3 -2
- package/dist/thread.js +153 -82
- package/dist/util.js +8 -1
- package/dist/verify.js +141 -52
- package/dist/vida-da-thread.js +254 -0
- package/dist/worktree-local.js +165 -0
- package/dist/worktree.js +20 -0
- package/dist/yaml.js +27 -8
- package/package.json +1 -1
- package/schemas/code-artifact-graph.v1.schema.json +2 -1
package/dist/thread.js
CHANGED
|
@@ -39,6 +39,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
39
39
|
};
|
|
40
40
|
})();
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.TETO_DO_PEDIDO = exports.ARQUIVO_DO_PEDIDO = void 0;
|
|
42
43
|
exports.dirThreads = dirThreads;
|
|
43
44
|
exports.dirThread = dirThread;
|
|
44
45
|
exports.caminhoThread = caminhoThread;
|
|
@@ -57,6 +58,8 @@ exports.avisoDeThreadSemWorktree = avisoDeThreadSemWorktree;
|
|
|
57
58
|
exports.avisoDeWorktreeQueFalharia = avisoDeWorktreeQueFalharia;
|
|
58
59
|
exports.avisoDeChaveSemCommit = avisoDeChaveSemCommit;
|
|
59
60
|
exports.avisoDaWorktree = avisoDaWorktree;
|
|
61
|
+
exports.prepararPedido = prepararPedido;
|
|
62
|
+
exports.pedidoDaThread = pedidoDaThread;
|
|
60
63
|
exports.novaThread = novaThread;
|
|
61
64
|
exports.exigirVarianteCompativel = exigirVarianteCompativel;
|
|
62
65
|
exports.blocoDaThread = blocoDaThread;
|
|
@@ -67,12 +70,14 @@ exports.resumoDaThread = resumoDaThread;
|
|
|
67
70
|
exports.threadsDaListagem = threadsDaListagem;
|
|
68
71
|
exports.tabelaDeThreads = tabelaDeThreads;
|
|
69
72
|
exports.exigirFase = exigirFase;
|
|
73
|
+
const worktree_local_1 = require("./worktree-local");
|
|
70
74
|
const fs = __importStar(require("node:fs"));
|
|
71
75
|
const path = __importStar(require("node:path"));
|
|
72
76
|
const ciclos_1 = require("./ciclos");
|
|
73
77
|
const modos_1 = require("./modos");
|
|
74
78
|
const manifest_1 = require("./manifest");
|
|
75
79
|
const slug_1 = require("./slug");
|
|
80
|
+
const node_crypto_1 = require("node:crypto");
|
|
76
81
|
const types_1 = require("./types");
|
|
77
82
|
const util_1 = require("./util");
|
|
78
83
|
const ledger_1 = require("./ledger");
|
|
@@ -81,6 +86,7 @@ const creation_operation_store_1 = require("./creation-operation-store");
|
|
|
81
86
|
const horario_1 = require("./horario");
|
|
82
87
|
const maquina_1 = require("./maquina");
|
|
83
88
|
const conducao_texto_1 = require("./conducao-texto");
|
|
89
|
+
const locale_1 = require("./locale");
|
|
84
90
|
/** Diretorio de threads do projeto. */
|
|
85
91
|
function dirThreads(raiz) {
|
|
86
92
|
return path.join((0, manifest_1.dirEstado)((0, estado_thread_1.raizDoEstado)(raiz)), 'threads');
|
|
@@ -108,7 +114,7 @@ function listarIds(raiz) {
|
|
|
108
114
|
function lerThread(raiz, id) {
|
|
109
115
|
const caminho = caminhoThread(raiz, id);
|
|
110
116
|
if (!fs.existsSync(caminho)) {
|
|
111
|
-
throw new
|
|
117
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.naoEncontrada(id, dirThreads(raiz)));
|
|
112
118
|
}
|
|
113
119
|
return (0, util_1.lerJson)(caminho);
|
|
114
120
|
}
|
|
@@ -133,11 +139,7 @@ function carimbarBase(raiz) {
|
|
|
133
139
|
function avisoDeThreadSemBase(thread, gravada) {
|
|
134
140
|
if (thread.base.commit !== util_1.COMMIT_DESCONHECIDO)
|
|
135
141
|
return null;
|
|
136
|
-
return gravada
|
|
137
|
-
? `Aviso: o repositório ainda não tem commit, e a thread ${thread.id} nasceu sem base: o ship não tem de onde partir. ` +
|
|
138
|
-
`Faça o primeiro commit, feche esta com ork thread close ${thread.id} --motivo engano --por <quem> ` +
|
|
139
|
-
'--justificativa "aberta antes do primeiro commit" e abra outra.'
|
|
140
|
-
: 'Aviso: o repositório ainda não tem commit, e a thread nasceria sem base: faça o primeiro commit antes de abrir a primeira thread.';
|
|
142
|
+
return (0, locale_1.msg)().thread.semBase(thread.id, gravada);
|
|
141
143
|
}
|
|
142
144
|
/** Resolve um id livre a partir do assunto normalizado (`<abbrev>-<assunto>`). */
|
|
143
145
|
function idDisponivel(raiz, abbrev, assunto) {
|
|
@@ -196,6 +198,8 @@ function worktreePrevista(carregado, id, slug, opcoes = {}) {
|
|
|
196
198
|
*/
|
|
197
199
|
function criarWorktree(carregado, id, slug, opcoes = {}) {
|
|
198
200
|
const { raiz, manifesto } = carregado;
|
|
201
|
+
// RM-047 (P3): worktree.dir do manifesto fora da raiz só cria checkout com a confirmação desta máquina.
|
|
202
|
+
(0, worktree_local_1.exigirPastaDasWorktrees)(raiz, manifesto);
|
|
199
203
|
const { dir, branch } = alvoDaWorktree(carregado, id, slug, opcoes);
|
|
200
204
|
if (fs.existsSync(dir)) {
|
|
201
205
|
throw new Error(`worktree ja existe em ${dir}`);
|
|
@@ -232,13 +236,12 @@ function criarWorktree(carregado, id, slug, opcoes = {}) {
|
|
|
232
236
|
function pedidoDeWorktree(flags, porThread) {
|
|
233
237
|
const worktree = flags.worktree === false ? undefined : flags.worktree;
|
|
234
238
|
if (typeof worktree === 'string' && !worktree.trim())
|
|
235
|
-
throw new Error(
|
|
236
|
-
if (typeof flags.semWorktree === 'string')
|
|
237
|
-
throw new Error(
|
|
238
|
-
}
|
|
239
|
+
throw new Error((0, locale_1.msg)().thread.worktreeVazia);
|
|
240
|
+
if (typeof flags.semWorktree === 'string')
|
|
241
|
+
throw new Error((0, locale_1.msg)().thread.semWorktreeComValor(flags.semWorktree));
|
|
239
242
|
const semWorktree = flags.semWorktree === true;
|
|
240
243
|
if (semWorktree && worktree !== undefined)
|
|
241
|
-
throw new Error(
|
|
244
|
+
throw new Error((0, locale_1.msg)().thread.worktreeESemWorktree);
|
|
242
245
|
if (semWorktree)
|
|
243
246
|
return { criar: false, dir: null, origem: 'sem-worktree' };
|
|
244
247
|
if (worktree === true || worktree === 'auto')
|
|
@@ -254,13 +257,12 @@ function pedidoDeWorktree(flags, porThread) {
|
|
|
254
257
|
function linhaDaWorktree(por, gravada, variante) {
|
|
255
258
|
if (!por || (gravada && por !== 'chave'))
|
|
256
259
|
return null;
|
|
257
|
-
const
|
|
258
|
-
if (por === 'chave')
|
|
259
|
-
return
|
|
260
|
-
}
|
|
260
|
+
const m = (0, locale_1.msg)().thread;
|
|
261
|
+
if (por === 'chave')
|
|
262
|
+
return m.worktreeChave(gravada);
|
|
261
263
|
if (por === 'flag')
|
|
262
|
-
return
|
|
263
|
-
return
|
|
264
|
+
return m.worktreeFlag(gravada);
|
|
265
|
+
return m.worktreeCiclo(gravada, variante ?? null);
|
|
264
266
|
}
|
|
265
267
|
/**
|
|
266
268
|
* P4 do ensaio da 0.5.0: o que acontece no SHIP com a thread criada por `--sem-worktree`. O `ork ship` entrega a
|
|
@@ -271,49 +273,27 @@ function linhaDaWorktree(por, gravada, variante) {
|
|
|
271
273
|
function avisoDeThreadSemWorktree(thread, manifesto, gravada = true) {
|
|
272
274
|
const base = manifesto.worktree.base_branch;
|
|
273
275
|
const branch = thread.base.branch;
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
if (branch === 'HEAD') {
|
|
284
|
-
return `${inicio}, com o HEAD destacado, fora de qualquer branch, e o ork ship não tem branch de origem para entregar. ${ensure}.`;
|
|
285
|
-
}
|
|
286
|
-
if (branch !== base) {
|
|
287
|
-
return `${inicio}, na branch ${branch}, e o ork ship entrega essa branch como estiver, com o que mais entrar nela; ` +
|
|
288
|
-
`com --para ${branch}, a entrega vira push direto, que a policy push_direto_na_base confere. ${ensure}.`;
|
|
289
|
-
}
|
|
276
|
+
const aviso = (c) => (0, locale_1.msg)().thread.avisoSemWorktree(thread.id, gravada, c);
|
|
277
|
+
// Sem commit, nem o `ork worktree ensure` tem de onde partir: o caminho e o do aviso de thread sem base.
|
|
278
|
+
if (thread.base.commit === util_1.COMMIT_DESCONHECIDO)
|
|
279
|
+
return aviso({ caso: 'sem-commit' });
|
|
280
|
+
if (branch === 'HEAD')
|
|
281
|
+
return aviso({ caso: 'head' });
|
|
282
|
+
if (branch !== base)
|
|
283
|
+
return aviso({ caso: 'outra', branch });
|
|
290
284
|
const policy = manifesto.policies?.push_direto_na_base;
|
|
291
|
-
|
|
292
|
-
? 'o ork ship barra a entrega por push_direto_na_base (block): não há branch de thread para mergear'
|
|
293
|
-
: policy === undefined || policy === 'off'
|
|
294
|
-
? 'o ork ship empurra a base direto, sem branch de thread (push_direto_na_base desligada)'
|
|
295
|
-
: `o ork ship avisa push_direto_na_base (${policy}) e empurra a base direto, sem branch de thread`;
|
|
296
|
-
return `${inicio}, na branch base ${base}, e ${efeito}. ${ensure}; depois do GO, os commits já estão na base e o ship não os separa.`;
|
|
285
|
+
return aviso({ caso: 'base', base, policy: policy === undefined ? undefined : String(policy) });
|
|
297
286
|
}
|
|
298
287
|
/**
|
|
299
288
|
* P4 do ensaio da 0.5.0 (CHECK): no `--dry-run`, por que a criacao de verdade recusaria a worktree, em vez de preve-la.
|
|
300
289
|
* O ciclo que exige worktree nao aceita `--sem-worktree`, entao a saida so e sugerida para a chave e a flag.
|
|
301
290
|
*/
|
|
302
291
|
function avisoDeWorktreeQueFalharia(f) {
|
|
303
|
-
|
|
304
|
-
if (f.motivo === 'pasta-existe') {
|
|
305
|
-
return `Aviso: a pasta ${f.dir} já existe, e a criação de verdade recusaria a worktree da thread: tire a pasta${semWorktree}.`;
|
|
306
|
-
}
|
|
307
|
-
if (f.motivo === 'branch-existe') {
|
|
308
|
-
return `Aviso: a branch ${f.branch} já existe, e a criação de verdade recusaria a worktree da thread: tire a branch${semWorktree}.`;
|
|
309
|
-
}
|
|
310
|
-
return 'Aviso: o repositório ainda não tem commit, e a criação de verdade recusaria a worktree da thread no git worktree add: ' +
|
|
311
|
-
'faça o primeiro commit antes.';
|
|
292
|
+
return (0, locale_1.msg)().thread.worktreeFalharia(f.motivo, f.dir, f.branch, f.por === 'ciclo');
|
|
312
293
|
}
|
|
313
294
|
/** P4 do ensaio da 0.5.0: a worktree que a chave pede nao tem de onde partir num repositorio sem commit. */
|
|
314
295
|
function avisoDeChaveSemCommit(gravada) {
|
|
315
|
-
return
|
|
316
|
-
`a thread ${gravada ? 'nasceu' : 'nasceria'} na raiz do projeto, sem worktree.`;
|
|
296
|
+
return (0, locale_1.msg)().thread.chaveSemCommit(gravada);
|
|
317
297
|
}
|
|
318
298
|
/** P4: o aviso de worktree do `ork thread new`, para o stderr, ou `null` quando nao ha o que avisar. */
|
|
319
299
|
function avisoDaWorktree(origem, resultado, manifesto) {
|
|
@@ -323,6 +303,86 @@ function avisoDaWorktree(origem, resultado, manifesto) {
|
|
|
323
303
|
return avisoDeChaveSemCommit(resultado.gravada);
|
|
324
304
|
return null;
|
|
325
305
|
}
|
|
306
|
+
/** RM-059 (T6.0): o arquivo do pedido guardado, na pasta da thread. */
|
|
307
|
+
exports.ARQUIVO_DO_PEDIDO = 'pedido.md';
|
|
308
|
+
/**
|
|
309
|
+
* O prompt da fase vai inteiro como UM argumento do `claude --bg`, e o Linux recusa argumento acima de
|
|
310
|
+
* 128 KiB (MAX_ARG_STRLEN); o pedido fica com a metade, para o template caber junto.
|
|
311
|
+
*/
|
|
312
|
+
exports.TETO_DO_PEDIDO = 64 * 1024;
|
|
313
|
+
/** O pedido como ele vai ser guardado: sem espaco nas pontas, nao vazio e dentro do teto. */
|
|
314
|
+
function prepararPedido(bruto) {
|
|
315
|
+
const texto = bruto.trim();
|
|
316
|
+
if (!texto)
|
|
317
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.pedidoVazio);
|
|
318
|
+
const bytes = Buffer.byteLength(texto, 'utf8');
|
|
319
|
+
if (bytes > exports.TETO_DO_PEDIDO)
|
|
320
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.pedidoGrande(bytes, exports.TETO_DO_PEDIDO));
|
|
321
|
+
return { texto, meta: { arquivo: exports.ARQUIVO_DO_PEDIDO, sha256: (0, node_crypto_1.createHash)('sha256').update(texto, 'utf8').digest('hex'), bytes } };
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* RM-059 (T6.0): o pedido guardado na criacao da thread, conferido contra o sha256 gravado; `null` na
|
|
325
|
+
* thread criada sem pedido. Arquivo que falta ou que nao bate com o sha256 (editado fora do nucleo) e
|
|
326
|
+
* erro tipado: o render nunca usa um pedido sem a prova de que e o da criacao.
|
|
327
|
+
*/
|
|
328
|
+
function pedidoDaThread(raiz, thread) {
|
|
329
|
+
const meta = thread.pedido;
|
|
330
|
+
if (!meta)
|
|
331
|
+
return null;
|
|
332
|
+
const restaurar = 'passe --pedido no render ou restaure o arquivo';
|
|
333
|
+
// O nome do arquivo e fixo: um thread.json editado nao aponta o render para outro arquivo do projeto.
|
|
334
|
+
if (meta.arquivo !== exports.ARQUIVO_DO_PEDIDO || !/^[a-f0-9]{64}$/.test(String(meta.sha256))) {
|
|
335
|
+
throw new Error(`thread.pedido.divergente: o pedido da thread ${thread.id} no thread.json nao e o que a criacao grava; ${restaurar}`);
|
|
336
|
+
}
|
|
337
|
+
const arquivo = path.join(dirThread(raiz, thread.id), exports.ARQUIVO_DO_PEDIDO);
|
|
338
|
+
let fd;
|
|
339
|
+
try {
|
|
340
|
+
fd = fs.openSync(arquivo, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
|
|
341
|
+
}
|
|
342
|
+
catch (e) {
|
|
343
|
+
if (e.code === 'ENOENT')
|
|
344
|
+
throw new Error(`thread.pedido.ausente: a thread ${thread.id} guardou o pedido em ${meta.arquivo} e ele sumiu; ${restaurar}`);
|
|
345
|
+
throw new Error(`thread.pedido.divergente: ${meta.arquivo} da thread ${thread.id} nao abre como arquivo comum; ${restaurar}`);
|
|
346
|
+
}
|
|
347
|
+
try {
|
|
348
|
+
const st = fs.fstatSync(fd);
|
|
349
|
+
if (!st.isFile() || st.size > exports.TETO_DO_PEDIDO)
|
|
350
|
+
throw new Error(`thread.pedido.divergente: ${meta.arquivo} da thread ${thread.id} nao e o arquivo guardado; ${restaurar}`);
|
|
351
|
+
const bytes = fs.readFileSync(fd);
|
|
352
|
+
const sha256 = (0, node_crypto_1.createHash)('sha256').update(bytes).digest('hex');
|
|
353
|
+
if (sha256 !== meta.sha256) {
|
|
354
|
+
throw new Error(`thread.pedido.divergente: ${meta.arquivo} da thread ${thread.id} nao bate com o sha256 gravado na criacao ` +
|
|
355
|
+
`(${(0, util_1.shaCurto)(meta.sha256)}): foi editado fora do nucleo; ${restaurar}`);
|
|
356
|
+
}
|
|
357
|
+
return { texto: bytes.toString('utf8'), sha256 };
|
|
358
|
+
}
|
|
359
|
+
finally {
|
|
360
|
+
fs.closeSync(fd);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Grava o pedido sem meio-termo: escreve num temporario com fsync e o liga ao nome final, que nao pode existir
|
|
365
|
+
* (o `link` recusa sobrescrever). Uma falha no meio nao deixa `pedido.md` pela metade.
|
|
366
|
+
*/
|
|
367
|
+
function gravarPedido(dir, texto) {
|
|
368
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
369
|
+
const alvo = path.join(dir, exports.ARQUIVO_DO_PEDIDO);
|
|
370
|
+
const temporario = path.join(dir, `.${exports.ARQUIVO_DO_PEDIDO}.${process.pid}.${Date.now()}.tmp`);
|
|
371
|
+
const fd = fs.openSync(temporario, 'wx', 0o600);
|
|
372
|
+
try {
|
|
373
|
+
try {
|
|
374
|
+
fs.writeFileSync(fd, texto, 'utf8');
|
|
375
|
+
fs.fsyncSync(fd);
|
|
376
|
+
}
|
|
377
|
+
finally {
|
|
378
|
+
fs.closeSync(fd);
|
|
379
|
+
}
|
|
380
|
+
fs.linkSync(temporario, alvo);
|
|
381
|
+
}
|
|
382
|
+
finally {
|
|
383
|
+
fs.rmSync(temporario, { force: true });
|
|
384
|
+
}
|
|
385
|
+
}
|
|
326
386
|
/** Cria a thread: valida modo contra o manifesto, gera o slug e carimba a base. */
|
|
327
387
|
function novaThread(carregado, opcoes) {
|
|
328
388
|
if (opcoes.dryRun)
|
|
@@ -342,21 +402,23 @@ function exigirVarianteCompativel(variante, def) {
|
|
|
342
402
|
return;
|
|
343
403
|
const [unico, ...resto] = def.blocos;
|
|
344
404
|
if (unico && resto.length === 0 && unico.fases.length < types_1.FASES.length) {
|
|
345
|
-
throw new
|
|
346
|
-
`(${unico.fases.join('-')}): crie a thread sem --ciclo ou escolha um modo de ciclo completo`);
|
|
405
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.varianteIncompativel(variante, def.tag, unico.fases.join('-')));
|
|
347
406
|
}
|
|
348
407
|
}
|
|
349
408
|
function criarThreadSerializada(carregado, opcoes) {
|
|
350
409
|
const { raiz, manifesto } = carregado;
|
|
351
410
|
const permitidos = manifesto.conduction.allowed_modes;
|
|
352
411
|
if (!permitidos.includes(opcoes.modo)) {
|
|
353
|
-
|
|
354
|
-
|
|
412
|
+
const tag = modos_1.MODOS[opcoes.modo].tag, lista = permitidos.map((p) => modos_1.MODOS[p].tag).join(', ');
|
|
413
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.modoNaoPermitido(tag, lista));
|
|
355
414
|
}
|
|
356
415
|
const assuntoBruto = (0, slug_1.normalizarAssunto)(opcoes.assunto ?? opcoes.nome);
|
|
357
416
|
if (!assuntoBruto) {
|
|
358
|
-
|
|
417
|
+
const nome = opcoes.nome;
|
|
418
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.nomeSemAssunto(nome));
|
|
359
419
|
}
|
|
420
|
+
// RM-059 (T6.0): o pedido e conferido antes de qualquer gravacao, tambem no ensaio.
|
|
421
|
+
const pedido = opcoes.pedido !== undefined ? prepararPedido(opcoes.pedido) : null;
|
|
360
422
|
const abbrev = manifesto.project.abbrev;
|
|
361
423
|
const def = (0, modos_1.definicaoDoModo)(opcoes.modo);
|
|
362
424
|
const variante = opcoes.variante ?? null;
|
|
@@ -368,17 +430,18 @@ function criarThreadSerializada(carregado, opcoes) {
|
|
|
368
430
|
if (variante) {
|
|
369
431
|
const dv = (0, ciclos_1.definicaoDaVariante)(variante);
|
|
370
432
|
if (dv.exigeBranch && !opcoes.branch) {
|
|
371
|
-
throw new
|
|
433
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.cicloExigeBranch(variante));
|
|
372
434
|
}
|
|
373
|
-
|
|
374
|
-
|
|
435
|
+
const branch = opcoes.branch;
|
|
436
|
+
if (branch) {
|
|
437
|
+
const existe = (0, util_1.exec)('git', ['rev-parse', '--verify', `refs/heads/${branch}`], raiz);
|
|
375
438
|
if (!existe.ok) {
|
|
376
|
-
throw new
|
|
439
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.branchInexistente(branch));
|
|
377
440
|
}
|
|
378
441
|
}
|
|
379
442
|
}
|
|
380
443
|
else if (opcoes.branch) {
|
|
381
|
-
throw new
|
|
444
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.branchSemCiclo);
|
|
382
445
|
}
|
|
383
446
|
// `greenfield`, `merge-branch` e `feature-xl-faseada` exigem worktree isolada: sao os
|
|
384
447
|
// ciclos que escrevem codigo em paralelo com outras threads.
|
|
@@ -419,7 +482,7 @@ function criarThreadSerializada(carregado, opcoes) {
|
|
|
419
482
|
const slug = opcoes.slug ?? (0, slug_1.montarSlug)(abbrev, assunto, blocos[0].slugFases);
|
|
420
483
|
// O override `--slug` do builder tambem passa pela regex canonica.
|
|
421
484
|
if (!(0, slug_1.slugValido)(slug)) {
|
|
422
|
-
throw new
|
|
485
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.slugInvalido(slug, slug_1.REGEX_SLUG.source));
|
|
423
486
|
}
|
|
424
487
|
const thread = {
|
|
425
488
|
...(origin ? { creationOrigin: origin } : {}),
|
|
@@ -442,6 +505,7 @@ function criarThreadSerializada(carregado, opcoes) {
|
|
|
442
505
|
sessoes: [],
|
|
443
506
|
...(opcoes.exigeRuntimeDiferente === true ? { exigeRuntimeDiferente: true } : {}),
|
|
444
507
|
...(opcoes.doneWhen && opcoes.doneWhen.length > 0 ? { doneWhen: opcoes.doneWhen } : {}),
|
|
508
|
+
...(pedido ? { pedido: pedido.meta } : {}),
|
|
445
509
|
decisoes: [],
|
|
446
510
|
claims: [],
|
|
447
511
|
leases: [],
|
|
@@ -478,8 +542,9 @@ function criarThreadSerializada(carregado, opcoes) {
|
|
|
478
542
|
const ocupadaPelaChave = pelaChave && !exigeWorktree && prevista &&
|
|
479
543
|
(prevista.falha === 'pasta-existe' || prevista.falha === 'branch-existe') ? prevista : null;
|
|
480
544
|
if (ocupadaPelaChave) {
|
|
481
|
-
const
|
|
482
|
-
|
|
545
|
+
const pasta = ocupadaPelaChave.falha === 'pasta-existe';
|
|
546
|
+
const alvo = pasta ? ocupadaPelaChave.dir : ocupadaPelaChave.branch;
|
|
547
|
+
throw new locale_1.ErroDoCatalogo((m) => m.thread.ocupadaPelaChave(pasta, alvo));
|
|
483
548
|
}
|
|
484
549
|
let worktreeCriada = null;
|
|
485
550
|
if (worktreePor) {
|
|
@@ -493,6 +558,10 @@ function criarThreadSerializada(carregado, opcoes) {
|
|
|
493
558
|
commit: commitDaBranch.ok ? commitDaBranch.stdout.trim() : thread.base.commit,
|
|
494
559
|
};
|
|
495
560
|
}
|
|
561
|
+
// RM-059 (T6.0): o pedido vai ao lado do thread.json, so com permissao do dono, como ele, e antes dele: o
|
|
562
|
+
// thread.json nunca aponta para um pedido que nao foi gravado.
|
|
563
|
+
if (pedido)
|
|
564
|
+
gravarPedido(dirThread(raiz, id), pedido.texto);
|
|
496
565
|
gravarThread(raiz, thread);
|
|
497
566
|
(0, ledger_1.registrar)(dirThread(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.threadCriada, {
|
|
498
567
|
...(origin ? { creationOrigin: origin } : {}),
|
|
@@ -510,6 +579,7 @@ function criarThreadSerializada(carregado, opcoes) {
|
|
|
510
579
|
branchDeOrigem: opcoes.branch ?? null,
|
|
511
580
|
maquina: thread.maquina,
|
|
512
581
|
...(thread.roadmap ? { roadmap: thread.roadmap } : {}),
|
|
582
|
+
...(pedido ? { pedido: pedido.meta } : {}),
|
|
513
583
|
});
|
|
514
584
|
if (worktreeCriada) {
|
|
515
585
|
(0, ledger_1.registrar)(dirThread(raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeCriada, {
|
|
@@ -552,38 +622,39 @@ function canalDaSessao(s) {
|
|
|
552
622
|
}
|
|
553
623
|
function resumoDaThread(thread, conducao) {
|
|
554
624
|
const def = (0, modos_1.definicaoDoModo)(thread.modo);
|
|
625
|
+
const m = (0, locale_1.msg)().thread, r = m.rotulos;
|
|
626
|
+
// RM-061 (F2a): o rotulo vem do catalogo, na largura do locale; o valor gravado (nome, criterio) sai como esta.
|
|
627
|
+
const campo = (rotulo, valor) => ` ${rotulo.padEnd(m.largura)} ${valor}`;
|
|
555
628
|
const linhas = [];
|
|
556
|
-
linhas.push(
|
|
557
|
-
linhas.push(
|
|
558
|
-
linhas.push(
|
|
559
|
-
linhas.push(
|
|
560
|
-
linhas.push(
|
|
561
|
-
linhas.push(
|
|
562
|
-
linhas.push(
|
|
563
|
-
linhas.push(
|
|
564
|
-
linhas.push(
|
|
629
|
+
linhas.push(campo(r.id, thread.id));
|
|
630
|
+
linhas.push(campo(r.slug, thread.slug));
|
|
631
|
+
linhas.push(campo(r.nome, thread.nome));
|
|
632
|
+
linhas.push(campo(r.modo, m.modo(def.tag, pausasDaThread(thread))));
|
|
633
|
+
linhas.push(campo(r.ciclo, thread.variante ?? m.cicloPadrao));
|
|
634
|
+
linhas.push(campo(r.fase, thread.faseAtual));
|
|
635
|
+
linhas.push(campo(r.status, m.status(thread.status)));
|
|
636
|
+
linhas.push(campo(r.base, `${thread.base.branch} @ ${(0, util_1.shaCurto)(thread.base.commit)}`));
|
|
637
|
+
linhas.push(campo(r.worktree, thread.worktree ?? m.raizDoProjeto));
|
|
565
638
|
// I-36 (T17): quem passa a leitura da conducao ve a linha unica; sem ela o resumo fica como era.
|
|
566
639
|
if (conducao !== undefined)
|
|
567
|
-
linhas.push(
|
|
640
|
+
linhas.push(campo(r.conducao, conducao ? (0, conducao_texto_1.linhaDeConducao)(conducao) : m.ninguemConduz));
|
|
568
641
|
// I-43 (D4, viga a): a exigencia so aparece quando existe, para nao poluir o resumo
|
|
569
642
|
// das threads que nao a declararam.
|
|
570
|
-
if (thread.exigeRuntimeDiferente === true)
|
|
571
|
-
linhas.push(
|
|
572
|
-
}
|
|
643
|
+
if (thread.exigeRuntimeDiferente === true)
|
|
644
|
+
linhas.push(m.validacao);
|
|
573
645
|
// I-43 (D4, viga b): o criterio aparece COM o comando. Mostrar so o criterio seria
|
|
574
646
|
// reproduzir a prosa do envelope numa tela nova.
|
|
575
647
|
if (thread.doneWhen && thread.doneWhen.length > 0) {
|
|
576
|
-
linhas.push(
|
|
648
|
+
linhas.push(m.prontoQuando(thread.doneWhen.length));
|
|
577
649
|
for (const d of thread.doneWhen)
|
|
578
650
|
linhas.push(` ${d.criterio}\n $ ${d.comando}`);
|
|
579
651
|
}
|
|
580
652
|
if (thread.score) {
|
|
581
|
-
linhas.push(
|
|
582
|
-
`(${thread.score.regime}) em ${(0, horario_1.formatarDataHoraRotulada)(thread.score.avaliadoEm)}`);
|
|
653
|
+
linhas.push(campo(r.score, m.score(thread.score.valor, thread.score.avaliadoPor, thread.score.regime, (0, horario_1.formatarDataHoraRotulada)(thread.score.avaliadoEm))));
|
|
583
654
|
}
|
|
584
|
-
linhas.push(
|
|
655
|
+
linhas.push(m.blocosPrevistos);
|
|
585
656
|
for (const b of thread.blocos) {
|
|
586
|
-
const marca = b.pausa ?
|
|
657
|
+
const marca = b.pausa ? m.pausaPrevista(m.pausaSobre(b.pausaSobre)) : m.semPausa;
|
|
587
658
|
linhas.push(` ${b.slugFases.padEnd(6)} ${b.fases.join('-').padEnd(18)} ${marca}`);
|
|
588
659
|
}
|
|
589
660
|
return linhas.join('\n');
|
|
@@ -639,7 +710,7 @@ function tabelaDeThreads(raiz, opcoes = {}) {
|
|
|
639
710
|
function exigirFase(thread, bruto) {
|
|
640
711
|
const fase = bruto.toUpperCase();
|
|
641
712
|
if (!thread.fases.includes(fase)) {
|
|
642
|
-
throw new Error(
|
|
713
|
+
throw new Error((0, locale_1.msg)().phase.faseInvalida(bruto, thread.fases.join(', ')));
|
|
643
714
|
}
|
|
644
715
|
return fase;
|
|
645
716
|
}
|
package/dist/util.js
CHANGED
|
@@ -197,7 +197,14 @@ function lerJsonl(caminho) {
|
|
|
197
197
|
/** Anexa um registro ao armazem JSONL, criando o diretorio que faltar. */
|
|
198
198
|
function anexarJsonl(caminho, valor) {
|
|
199
199
|
fs.mkdirSync(path.dirname(caminho), { recursive: true });
|
|
200
|
-
|
|
200
|
+
// RM-047: O_NOFOLLOW; um armazém versionado como link (claims, board) não leva o append para fora da raiz.
|
|
201
|
+
const fd = fs.openSync(caminho, fs.constants.O_WRONLY | fs.constants.O_APPEND | fs.constants.O_CREAT | fs.constants.O_NOFOLLOW, 0o644);
|
|
202
|
+
try {
|
|
203
|
+
fs.writeFileSync(fd, JSON.stringify(valor) + '\n', 'utf8');
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
fs.closeSync(fd);
|
|
207
|
+
}
|
|
201
208
|
}
|
|
202
209
|
/** Proximo id sequencial de um armazem (`C1`, `C2`, ... / `F1`, `F2`, ...). */
|
|
203
210
|
function proximoIdSequencial(ids, prefixo) {
|