@orkastery/cli 0.5.6 → 0.6.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.
- package/adapters/README.md +18 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
- package/adapters/claude-code/README.md +37 -5
- package/adapters/claude-code/agents/ork-check.md +1 -0
- package/adapters/claude-code/agents/ork-go.md +1 -0
- package/adapters/claude-code/agents/ork-goal.md +1 -0
- package/adapters/claude-code/agents/ork-master.md +1 -0
- package/adapters/claude-code/agents/ork-plan.md +1 -0
- package/adapters/claude-code/agents/ork-ship.md +1 -0
- package/adapters/claude-code/hooks/hooks.json +2 -1
- package/adapters/claude-code/hooks/ork-guard.js +15 -1
- package/adapters/claude-code/hooks/ork-resposta.js +91 -0
- package/adapters/claude-code/hooks/ork-sensor.js +18 -2
- package/adapters/claude-code/hooks/quota-signal.js +14 -0
- package/adapters/claude-code/mods/ork-mensageiro/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
- package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +9 -5
- package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
- package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +1 -1
- package/adapters/codex/skills/ork/SKILL.md +2 -0
- package/adapters/hermes/README.md +64 -1
- package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
- package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
- package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
- package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
- package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
- package/adapters/hermes/hermes.plugin.json +4 -0
- package/adapters/hermes/hitl-ingress/__init__.py +101 -8
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +2 -2
- package/adapters/openclaw/README.md +81 -9
- package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
- package/adapters/openclaw/dist/hitl-ingress.js +106 -9
- package/adapters/openclaw/dist/index.js +86 -0
- package/adapters/openclaw/openclaw.plugin.json +34 -4
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +103 -9
- package/adapters/openclaw/src/index.ts +94 -0
- package/assets/adapters-en/claude-code/README.md +403 -0
- package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
- package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
- package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
- package/assets/adapters-en/claude-code/commands/check.md +46 -0
- package/assets/adapters-en/claude-code/commands/go.md +46 -0
- package/assets/adapters-en/claude-code/commands/goal.md +55 -0
- package/assets/adapters-en/claude-code/commands/master.md +54 -0
- package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
- package/assets/adapters-en/claude-code/commands/ork.md +126 -0
- package/assets/adapters-en/claude-code/commands/plan.md +47 -0
- package/assets/adapters-en/claude-code/commands/ship.md +45 -0
- package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
- package/assets/adapters-en/hermes/README.md +273 -0
- package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
- package/assets/references-en/README.md +25 -0
- package/assets/references-en/code-review-axes.md +82 -0
- package/assets/references-en/definition-of-done.md +74 -0
- package/assets/references-en/performance-checklist.md +53 -0
- package/assets/references-en/security-checklist.md +101 -0
- package/assets/references-en/testing-patterns.md +51 -0
- package/assets/security-scan/defaults/.golangci.yml +2 -0
- package/assets/security-scan/defaults/eslint.config.mjs +11 -0
- package/assets/security-scan/defaults/gitleaks.toml +3 -0
- package/assets/security-scan/defaults/ruff.toml +1 -0
- package/assets/security-scan/tools-agil.json +87 -0
- package/assets/security-scan/tools.json +625 -0
- package/assets/skills-en/core/onboarding/SKILL.md +58 -0
- package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
- package/assets/skills-en/core/thread-state/SKILL.md +88 -0
- package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
- package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
- package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
- package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
- package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
- package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
- package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
- package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
- package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
- package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
- package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
- package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
- package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
- package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
- package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
- package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
- package/dist/adapters/claude-bg.js +123 -9
- package/dist/adapters/codex-controller-worker.js +12 -5
- package/dist/adapters/codex-events.js +16 -4
- package/dist/adapters/codex.js +3 -1
- package/dist/adapters/grok-events.js +227 -0
- package/dist/adapters/grok-mcp-servidor.js +612 -0
- package/dist/adapters/grok-mcp.js +178 -0
- package/dist/adapters/grok.js +686 -0
- package/dist/agendador-cpu.js +92 -0
- package/dist/atualizar-branch.js +245 -0
- package/dist/auditoria.js +13 -11
- package/dist/auditrun.js +51 -46
- package/dist/autorizacao-duravel.js +327 -0
- package/dist/board.js +94 -40
- package/dist/branch-de-estado.js +23 -10
- package/dist/busca-semantica.js +7 -5
- package/dist/catalogo.js +2 -1
- package/dist/changelog-reconciliacao.js +290 -0
- package/dist/check-agil.js +528 -0
- package/dist/check-modo.js +41 -0
- package/dist/check-paralelo.js +238 -0
- package/dist/ci.js +248 -45
- package/dist/ciclos.js +8 -6
- package/dist/claim-lint.js +12 -8
- package/dist/claims-conferir.js +47 -39
- package/dist/claims.js +10 -9
- package/dist/company-brain-client.js +10 -3
- package/dist/company-brain-migration.js +11 -5
- package/dist/conducao-batida.js +759 -0
- package/dist/conducao-sentinela.js +25 -8
- package/dist/conducao.js +89 -29
- package/dist/conhecimento-consulta.js +270 -0
- package/dist/conhecimento.js +111 -87
- package/dist/conta-esgotada.js +127 -0
- package/dist/dado-privado.js +816 -0
- package/dist/decisao-autonoma.js +5 -4
- package/dist/demo.js +14 -12
- package/dist/dependencias-da-worktree.js +25 -0
- package/dist/divida.js +38 -36
- package/dist/docs.js +89 -89
- package/dist/doctor-forja.js +343 -0
- package/dist/doctor-pulse-cron.js +113 -1
- package/dist/doctor.js +164 -6
- package/dist/dsn-da-memoria.js +417 -0
- package/dist/entrega-por-mod.js +503 -0
- package/dist/entrega-pr.js +154 -54
- package/dist/esgotamentos.js +13 -11
- package/dist/estado-thread.js +21 -18
- package/dist/evalrunner.js +35 -32
- package/dist/fabrica-batida.js +34 -21
- package/dist/fabrica-estado.js +33 -21
- package/dist/fix.js +21 -19
- package/dist/forja/adaptador.js +6 -0
- package/dist/forja/ambiente-de-ci.js +27 -0
- package/dist/forja/api.js +256 -0
- package/dist/forja/cache.js +89 -0
- package/dist/forja/cli.js +60 -0
- package/dist/forja/contrato.js +9 -0
- package/dist/forja/endereco.js +43 -0
- package/dist/forja/estado.js +22 -0
- package/dist/forja/executor.js +73 -0
- package/dist/forja/github/ci.js +95 -0
- package/dist/forja/github/dono-da-rede.js +18 -0
- package/dist/forja/github/metadados.js +15 -0
- package/dist/forja/github/pedidos.js +200 -0
- package/dist/forja/gitlab/ci.js +141 -0
- package/dist/forja/gitlab/consultas.js +59 -0
- package/dist/forja/gitlab/dono-da-rede.js +43 -0
- package/dist/forja/gitlab/metadados.js +15 -0
- package/dist/forja/gitlab/pedidos-abertos.js +158 -0
- package/dist/forja/gitlab/pedidos.js +141 -0
- package/dist/forja/produtor.js +32 -0
- package/dist/forja/registro.js +31 -0
- package/dist/forja/resolver.js +121 -0
- package/dist/forja/texto.js +13 -0
- package/dist/forja/versao.js +71 -0
- package/dist/forja.js +123 -80
- package/dist/handoff.js +23 -13
- package/dist/hitl-contract.js +46 -43
- package/dist/hitl-curto.js +37 -25
- package/dist/hitl-gates.js +13 -11
- package/dist/hitl-local-receipt.js +51 -0
- package/dist/hitl-local.js +11 -2
- package/dist/hitl-lock.js +5 -11
- package/dist/hitl-public-receipt.js +11 -0
- package/dist/hitl-resumo.js +44 -1
- package/dist/hitl-sessions.js +62 -9
- package/dist/hitl-texto-livre.js +7 -4
- package/dist/hitl.js +34 -31
- package/dist/horario.js +20 -1
- package/dist/hosts.js +104 -134
- package/dist/index.js +864 -554
- package/dist/indice-vetorial.js +14 -12
- package/dist/init.js +11 -2
- package/dist/integracoes-locais.js +4 -0
- package/dist/intelligence-graph-cli.js +123 -69
- package/dist/intelligence-graph-query.js +37 -22
- package/dist/leases.js +19 -18
- package/dist/ledger-stats.js +17 -16
- package/dist/ledger.js +31 -1
- package/dist/licoes.js +12 -11
- package/dist/locale-accounts.js +228 -0
- package/dist/locale-adapter.js +291 -0
- package/dist/locale-ajuda.js +86 -10
- package/dist/locale-audit.js +199 -0
- package/dist/locale-claims.js +213 -0
- package/dist/locale-conducao.js +138 -0
- package/dist/locale-conhecimento.js +181 -0
- package/dist/locale-decisao.js +205 -0
- package/dist/locale-docs.js +230 -0
- package/dist/locale-estado.js +101 -0
- package/dist/locale-forja.js +288 -0
- package/dist/locale-gerados.js +5 -0
- package/dist/locale-grafo.js +129 -0
- package/dist/locale-master.js +83 -0
- package/dist/locale-network.js +524 -0
- package/dist/locale-operacao-restante.js +931 -0
- package/dist/locale-projetos.js +100 -0
- package/dist/locale-prompts.js +194 -0
- package/dist/locale-pulse.js +140 -2
- package/dist/locale-reservas.js +87 -0
- package/dist/locale-retry.js +183 -6
- package/dist/locale-security-scan.js +69 -0
- package/dist/locale-setup.js +192 -0
- package/dist/locale-ship.js +177 -66
- package/dist/locale-thread.js +149 -5
- package/dist/locale-verify.js +80 -4
- package/dist/locale-worktree.js +246 -0
- package/dist/locale.js +553 -9
- package/dist/maestro-runtime.js +22 -3
- package/dist/manifest.js +293 -12
- package/dist/maquina-ociosa.js +211 -0
- package/dist/maquina.js +10 -5
- package/dist/master-nota-local.js +200 -0
- package/dist/master-nota.js +10 -2
- package/dist/master.js +118 -41
- package/dist/mcp-conhecimento.js +52 -0
- package/dist/mcp-experiencia.js +26 -5
- package/dist/mcp-install.js +90 -15
- package/dist/mcp-noctum.js +101 -0
- package/dist/mcp-server.js +116 -22
- package/dist/mcp-ship-transporte.js +977 -0
- package/dist/mcp-ship.js +68 -24
- package/dist/mcp-transportes.js +17 -0
- package/dist/memoria.js +63 -58
- package/dist/merge-da-entrega.js +85 -0
- package/dist/modos-migracao.js +8 -6
- package/dist/modos.js +17 -18
- package/dist/network-roadmap.js +94 -54
- package/dist/noctum-aceite.js +929 -0
- package/dist/noctum-arco.js +540 -33
- package/dist/noctum-capacidade.js +3 -3
- package/dist/noctum-changelog.js +399 -0
- package/dist/noctum-cli.js +539 -0
- package/dist/noctum-coordenacao.js +1225 -0
- package/dist/noctum-entrega.js +1217 -0
- package/dist/noctum-envelope.js +253 -17
- package/dist/noctum-execucao.js +100 -24
- package/dist/noctum-fechamento.js +416 -0
- package/dist/noctum-fila.js +49 -10
- package/dist/noctum-guarda.js +333 -0
- package/dist/noctum-integracao.js +507 -0
- package/dist/noctum-maquinas.js +387 -0
- package/dist/noctum-medicao.js +450 -0
- package/dist/noctum-modo.js +390 -0
- package/dist/noctum-pergunta-canal.js +96 -0
- package/dist/noctum-pergunta.js +115 -0
- package/dist/noctum-provas.js +838 -0
- package/dist/noctum-reconciliacao.js +594 -0
- package/dist/noctum-rede.js +102 -0
- package/dist/noctum-registro.js +215 -0
- package/dist/noctum-relatorio.js +861 -0
- package/dist/noctum-resposta.js +207 -0
- package/dist/noctum-retomada-rede.js +71 -0
- package/dist/noctum-sessoes-em-voo.js +93 -0
- package/dist/noctum-supervisao.js +649 -0
- package/dist/noctum-terminal.js +459 -0
- package/dist/noctum-transporte.js +655 -0
- package/dist/noctum-vigia.js +679 -0
- package/dist/ocupacao.js +3 -1
- package/dist/onboarding.js +16 -5
- package/dist/orkmind.js +39 -23
- package/dist/orquestracao.js +31 -35
- package/dist/parado-no-condutor.js +160 -139
- package/dist/phase.js +96 -42
- package/dist/policies.js +33 -0
- package/dist/postura-local.js +11 -6
- package/dist/preflight.js +2 -1
- package/dist/procedencia.js +9 -14
- package/dist/projeto-alvo.js +59 -20
- package/dist/prompts.js +136 -42
- package/dist/prova-minima.js +5 -6
- package/dist/pulse-cadencia.js +5 -4
- package/dist/pulse-consentimento.js +53 -1
- package/dist/pulse-delivery.js +143 -27
- package/dist/pulse-resposta.js +368 -4
- package/dist/pulse.js +136 -3
- package/dist/ratelimit.js +13 -4
- package/dist/recall.js +14 -13
- package/dist/rede-adesao.js +13 -8
- package/dist/rede-forja.js +108 -24
- package/dist/rede-status.js +63 -45
- package/dist/rede.js +86 -46
- package/dist/retomada-checkpoint.js +101 -0
- package/dist/retry.js +326 -78
- package/dist/roadmap-reservas.js +32 -32
- package/dist/runtime-ambiente.js +5 -0
- package/dist/runtime-context.js +279 -85
- package/dist/runtime-escada.js +429 -0
- package/dist/runtime-profiles.js +130 -63
- package/dist/runtimes.js +42 -5
- package/dist/saida-segura.js +3 -2
- package/dist/security-scan/agil.js +366 -0
- package/dist/security-scan/cli.js +76 -0
- package/dist/security-scan/compare.js +149 -0
- package/dist/security-scan/config.js +93 -0
- package/dist/security-scan/detect.js +97 -0
- package/dist/security-scan/executor.js +196 -0
- package/dist/security-scan/guard.js +180 -0
- package/dist/security-scan/imagem-de-lint.js +96 -0
- package/dist/security-scan/normalize/actionlint.js +12 -0
- package/dist/security-scan/normalize/eslint.js +12 -0
- package/dist/security-scan/normalize/gitleaks.js +13 -0
- package/dist/security-scan/normalize/golangci-lint.js +13 -0
- package/dist/security-scan/normalize/govulncheck.js +36 -0
- package/dist/security-scan/normalize/index.js +25 -0
- package/dist/security-scan/normalize/npm-audit.js +30 -0
- package/dist/security-scan/normalize/osv-scanner.js +32 -0
- package/dist/security-scan/normalize/oxlint.js +51 -0
- package/dist/security-scan/normalize/pip-audit.js +16 -0
- package/dist/security-scan/normalize/ruff.js +12 -0
- package/dist/security-scan/normalize/semgrep.js +20 -0
- package/dist/security-scan/normalize/trivy.js +33 -0
- package/dist/security-scan/normalize/util.js +204 -0
- package/dist/security-scan/normalize/zizmor.js +19 -0
- package/dist/security-scan/report.js +156 -0
- package/dist/security-scan/run.js +448 -0
- package/dist/security-scan/tools.js +62 -0
- package/dist/security-scan/trabalhador.js +74 -0
- package/dist/security-scan/types.js +15 -0
- package/dist/session-events.js +19 -2
- package/dist/session-watcher-claude.js +74 -19
- package/dist/session-watcher-grok.js +425 -0
- package/dist/session-watcher.js +174 -13
- package/dist/sessoes-contas.js +42 -5
- package/dist/sessoes-inventario.js +1 -1
- package/dist/sessoes.js +25 -23
- package/dist/setup.js +67 -66
- package/dist/ship-publicar.js +263 -92
- package/dist/ship.js +160 -17
- package/dist/superficie.js +14 -11
- package/dist/thread-close.js +9 -9
- package/dist/thread.js +121 -18
- package/dist/tokens.js +15 -11
- package/dist/trabalho-thread.js +297 -0
- package/dist/transporte-do-canal.js +189 -0
- package/dist/types.js +12 -1
- package/dist/util.js +5 -2
- package/dist/varredura-acoes.js +500 -0
- package/dist/verify.js +491 -32
- package/dist/worktree-local.js +12 -10
- package/dist/worktree.js +81 -85
- package/eval/casos/check-quality.json +77 -0
- package/eval/casos/security-auditor.json +148 -0
- package/eval/casos/security-remediation.json +161 -0
- package/eval/fixtures/security-scan/README.md +8 -0
- package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/go/Dockerfile +4 -0
- package/eval/fixtures/security-scan/go/README.md +4 -0
- package/eval/fixtures/security-scan/go/config.go +4 -0
- package/eval/fixtures/security-scan/go/go.mod +5 -0
- package/eval/fixtures/security-scan/go/go.sum +2 -0
- package/eval/fixtures/security-scan/go/main.go +31 -0
- package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/js/Dockerfile +3 -0
- package/eval/fixtures/security-scan/js/README.md +4 -0
- package/eval/fixtures/security-scan/js/package-lock.json +844 -0
- package/eval/fixtures/security-scan/js/package.json +10 -0
- package/eval/fixtures/security-scan/js/src/config.js +4 -0
- package/eval/fixtures/security-scan/js/src/server.js +17 -0
- package/eval/fixtures/security-scan/js/src/util.ts +4 -0
- package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
- package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/python/Dockerfile +3 -0
- package/eval/fixtures/security-scan/python/README.md +4 -0
- package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
- package/eval/fixtures/security-scan/python/app/config.py +2 -0
- package/eval/fixtures/security-scan/python/app/main.py +19 -0
- package/eval/fixtures/security-scan/python/requirements.txt +1 -0
- package/package.json +10 -5
- package/references/security-checklist.md +3 -3
- package/skills/README.md +1 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/check-quality/SKILL.md +16 -0
- package/skills/phases/go-implementation/SKILL.md +6 -0
- package/skills/phases/security-remediation/SKILL.md +70 -0
- package/skills/reviewers/security-auditor/SKILL.md +25 -0
package/dist/rede-status.js
CHANGED
|
@@ -69,6 +69,20 @@ exports.SEM_BATIDA_MS = 3 * 60 * 60 * 1000;
|
|
|
69
69
|
/** O que esta leitura nunca olha: quem conclui sobre isso a partir daqui erra. */
|
|
70
70
|
exports.NAO_CONSULTADO = ['roadmap', 'reservas', 'threads'];
|
|
71
71
|
const mensagem = (e) => e.message.replace(/^[a-z.-]+: /, '');
|
|
72
|
+
/**
|
|
73
|
+
* RM-061 (F3b, G4): o detalhe da lacuna vai ao `--json` em pt-BR e nasce pelo catalogo; o erro de dentro (do catalogo
|
|
74
|
+
* ou nao) e remontado com ela.
|
|
75
|
+
*/
|
|
76
|
+
const lacunaDoCatalogo = (montar) => (0, locale_1.textoDoCatalogo)((m) => montar(m.network));
|
|
77
|
+
/**
|
|
78
|
+
* RM-061 (F3b, GO-FIX 1 do CHECK): o montador do texto de um erro, sem o codigo do comeco. O erro do catalogo guarda o
|
|
79
|
+
* proprio montador (o texto dele nao fica no registro); o resto sai como veio, ou pelo montador do texto embutido.
|
|
80
|
+
*/
|
|
81
|
+
function montadorDoErro(e) {
|
|
82
|
+
if (e instanceof locale_1.ErroDoCatalogo)
|
|
83
|
+
return (m) => e.montar(m).replace(/^[a-z.-]+: /, '');
|
|
84
|
+
return (0, locale_1.montadorDe)(mensagem(e));
|
|
85
|
+
}
|
|
72
86
|
/** Sem rede, a casa vem da adesao gravada ou da ultima publicacao desta maquina. */
|
|
73
87
|
function casaSemRede() {
|
|
74
88
|
const cfg = (0, rede_adesao_1.adesaoDaRede)().config;
|
|
@@ -102,7 +116,7 @@ function lerRede(o = {}) {
|
|
|
102
116
|
if (o.semRemoto) {
|
|
103
117
|
casa = casaSemRede();
|
|
104
118
|
if (!casa)
|
|
105
|
-
lacunas.push({ tipo: 'rede.sem-leitura', detalhe:
|
|
119
|
+
lacunas.push({ tipo: 'rede.sem-leitura', detalhe: lacunaDoCatalogo((m) => m.semRedeSemCasa) });
|
|
106
120
|
}
|
|
107
121
|
else {
|
|
108
122
|
const r = (0, rede_1.resolverCasa)({ amb: o.amb });
|
|
@@ -114,22 +128,25 @@ function lerRede(o = {}) {
|
|
|
114
128
|
const repo = r.forja.repositorio(r.casa.dono, r.casa.repositorio);
|
|
115
129
|
if (!repo.existe) {
|
|
116
130
|
ler = false;
|
|
117
|
-
|
|
131
|
+
const ref = (0, rede_1.refDaCasa)(r.casa);
|
|
132
|
+
lacunas.push({ tipo: 'rede.sem-repositorio', detalhe: lacunaDoCatalogo((m) => m.casaNaoExiste(ref)) });
|
|
118
133
|
}
|
|
119
134
|
else {
|
|
135
|
+
const ref = (0, rede_1.refDaCasa)(r.casa);
|
|
120
136
|
if (repo.privado !== true)
|
|
121
|
-
lacunas.push({ tipo: 'rede.repositorio-publico', detalhe:
|
|
137
|
+
lacunas.push({ tipo: 'rede.repositorio-publico', detalhe: lacunaDoCatalogo((m) => m.casaPublica(ref)) });
|
|
122
138
|
if (repo.url && (0, rede_1.urlDaCasaAceita)(repo.url))
|
|
123
139
|
(0, rede_1.prepararCache)(r.casa, repo.url, r.forja.helperDeCredencial(), eu);
|
|
124
140
|
else if (repo.url) {
|
|
125
141
|
// W10 da revisao 5: sem https nao ha leitura nova; o cache fica com a URL antiga e so a copia local vale.
|
|
126
142
|
semHttps = true;
|
|
127
|
-
lacunas.push({ tipo: 'rede.sem-leitura', detalhe:
|
|
143
|
+
lacunas.push({ tipo: 'rede.sem-leitura', detalhe: lacunaDoCatalogo((m) => m.casaSemHttps(ref)) });
|
|
128
144
|
}
|
|
129
145
|
}
|
|
130
146
|
}
|
|
131
147
|
catch (e) {
|
|
132
|
-
|
|
148
|
+
const ref = (0, rede_1.refDaCasa)(r.casa), erro = montadorDoErro(e);
|
|
149
|
+
lacunas.push({ tipo: 'rede.sem-leitura', detalhe: (0, locale_1.textoDoCatalogo)((m) => m.network.comErro(ref, erro(m))) });
|
|
133
150
|
}
|
|
134
151
|
}
|
|
135
152
|
}
|
|
@@ -145,16 +162,20 @@ function lerRede(o = {}) {
|
|
|
145
162
|
: (0, branch_de_estado_1.buscarBranch)(cache, 'origin', rede_1.BRANCH_DA_REDE, 'rede', o.timeoutMs ?? 30000));
|
|
146
163
|
fontes.push({ fonte: 'rede', ref: `${(0, rede_1.refDaCasa)(casa)}#${rede_1.BRANCH_DA_REDE}`, ponta, atualizado });
|
|
147
164
|
if (!atualizado && !soLocal) {
|
|
148
|
-
|
|
165
|
+
const ref = (0, rede_1.refDaCasa)(casa);
|
|
166
|
+
lacunas.push({ tipo: 'rede.sem-leitura', detalhe: lacunaDoCatalogo((m) => m.semLeituraNova(ref, !!ponta)) });
|
|
149
167
|
}
|
|
150
168
|
const lidos = (0, rede_1.retratosDaPonta)(cache, ponta);
|
|
151
169
|
lida = { cache, ponta };
|
|
152
170
|
retratos = lidos.retratos;
|
|
153
|
-
for (const inv of lidos.invalidos)
|
|
154
|
-
|
|
171
|
+
for (const inv of lidos.invalidos) {
|
|
172
|
+
const motivo = (0, locale_1.montadorDe)(inv.motivo);
|
|
173
|
+
lacunas.push({ tipo: 'retrato.invalido', detalhe: (0, locale_1.textoDoCatalogo)((m) => m.network.retratoInvalido(inv.arquivo, motivo(m))) });
|
|
174
|
+
}
|
|
155
175
|
}
|
|
156
176
|
else if (!lacunas.some((l) => l.tipo === 'rede.sem-leitura')) {
|
|
157
|
-
|
|
177
|
+
const ref = (0, rede_1.refDaCasa)(casa);
|
|
178
|
+
lacunas.push({ tipo: 'rede.sem-leitura', detalhe: lacunaDoCatalogo((m) => m.nuncaLida(ref)) });
|
|
158
179
|
}
|
|
159
180
|
}
|
|
160
181
|
for (const r of retratos)
|
|
@@ -172,7 +193,7 @@ function lerRede(o = {}) {
|
|
|
172
193
|
const projetos = o.soRaiz === undefined ? conhecidos : conhecidos.filter((p) => raizDe(p.caminho) === raizDe(o.soRaiz));
|
|
173
194
|
for (const p of projetos) {
|
|
174
195
|
if (!p.presente) {
|
|
175
|
-
lacunas.push({ tipo: 'projeto.sem-clone', projeto: p.nome, detalhe:
|
|
196
|
+
lacunas.push({ tipo: 'projeto.sem-clone', projeto: p.nome, detalhe: lacunaDoCatalogo((m) => m.semClone(p.nome, p.caminho)) });
|
|
176
197
|
continue;
|
|
177
198
|
}
|
|
178
199
|
let remoto = 'origin';
|
|
@@ -184,11 +205,11 @@ function lerRede(o = {}) {
|
|
|
184
205
|
// e o valor recusado sai redigido, sem a credencial de uma URL, no texto e no JSON.
|
|
185
206
|
if (!(0, branch_de_estado_1.remotoValido)(remoto)) {
|
|
186
207
|
lacunas.push({ tipo: 'fabrica.sem-leitura', projeto: p.nome,
|
|
187
|
-
detalhe:
|
|
208
|
+
detalhe: lacunaDoCatalogo((m) => m.remotoInvalido(p.nome, (0, branch_de_estado_1.remotoRedigido)(remoto))) });
|
|
188
209
|
continue;
|
|
189
210
|
}
|
|
190
211
|
if (!(0, rede_forja_1.comGitIsolado)(() => (0, branch_de_estado_1.git)(p.caminho, ['remote', 'get-url', '--', remoto]).ok)) {
|
|
191
|
-
lacunas.push({ tipo: 'fabrica.sem-leitura', projeto: p.nome, detalhe:
|
|
212
|
+
lacunas.push({ tipo: 'fabrica.sem-leitura', projeto: p.nome, detalhe: lacunaDoCatalogo((m) => m.semRemoto(p.nome, remoto)) });
|
|
192
213
|
continue;
|
|
193
214
|
}
|
|
194
215
|
try {
|
|
@@ -198,7 +219,7 @@ function lerRede(o = {}) {
|
|
|
198
219
|
const painel = (0, rede_forja_1.comGitIsolado)(() => (0, fabrica_estado_1.lerFabrica)(p.caminho, { remoto, semRemoto: o.semRemoto, timeoutMs: o.timeoutMs ?? 10000 }), undefined, { ssh: sshProprio ? 'herdado' : 'lote' });
|
|
199
220
|
fontes.push({ fonte: 'fabrica-estado', projeto: p.nome, ref: fabrica_estado_1.BRANCH_DA_FABRICA, ponta: painel.ponta, atualizado: painel.atualizado });
|
|
200
221
|
if (!painel.atualizado && !o.semRemoto) {
|
|
201
|
-
lacunas.push({ tipo: 'fabrica.sem-leitura', projeto: p.nome, detalhe:
|
|
222
|
+
lacunas.push({ tipo: 'fabrica.sem-leitura', projeto: p.nome, detalhe: lacunaDoCatalogo((m) => m.fabricaSemLeituraNova(p.nome, fabrica_estado_1.BRANCH_DA_FABRICA)) });
|
|
202
223
|
}
|
|
203
224
|
for (const bruto of painel.maquinas) {
|
|
204
225
|
// U4 da revisao 3: a fabrica guarda o nome cru, a rede o saneado; casam pelo saneado.
|
|
@@ -223,7 +244,8 @@ function lerRede(o = {}) {
|
|
|
223
244
|
}
|
|
224
245
|
}
|
|
225
246
|
catch (e) {
|
|
226
|
-
|
|
247
|
+
const erro = montadorDoErro(e);
|
|
248
|
+
lacunas.push({ tipo: 'fabrica.sem-leitura', projeto: p.nome, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.network.comErro(p.nome, erro(m))) });
|
|
227
249
|
}
|
|
228
250
|
}
|
|
229
251
|
// S7 da revisao 2: o retrato com o nome desta maquina pode ser de outra instalacao (tomou o nome).
|
|
@@ -242,17 +264,18 @@ function lerRede(o = {}) {
|
|
|
242
264
|
// e o `publicarRede` recusa com `rede.nome-em-uso`; o status diz o mesmo, em vez de chamar de "esta maquina".
|
|
243
265
|
const nomeEmUso = !!idNaCasa && idNaCasa !== meuId;
|
|
244
266
|
if (nomeEmUso) {
|
|
245
|
-
lacunas.push({ tipo: 'maquina.nome-em-uso', maquina: eu, detalhe:
|
|
246
|
-
'publica ate trocar de nome (ork network entrar --maquina NOME) ou retomar este (ork network entrar --forcar)' });
|
|
267
|
+
lacunas.push({ tipo: 'maquina.nome-em-uso', maquina: eu, detalhe: lacunaDoCatalogo((m) => m.nomeEmUsoNaCasa(eu)) });
|
|
247
268
|
}
|
|
248
269
|
// 4. O frescor de cada maquina (D15).
|
|
249
270
|
const lista = [...membros.values()].sort((a, b) => a.maquina.localeCompare(b.maquina));
|
|
250
271
|
for (const m of lista) {
|
|
251
272
|
// X5 da revisao 6: batida ilegivel (a fabrica legada aceita qualquer texto) nao passa por fresca.
|
|
252
273
|
if (!Number.isFinite(m.idadeMs))
|
|
253
|
-
lacunas.push({ tipo: 'maquina.sem-batida', maquina: m.maquina, detalhe:
|
|
254
|
-
else if (m.idadeMs > exports.SEM_BATIDA_MS)
|
|
255
|
-
|
|
274
|
+
lacunas.push({ tipo: 'maquina.sem-batida', maquina: m.maquina, detalhe: lacunaDoCatalogo((t) => t.batidaIlegivel(m.maquina)) });
|
|
275
|
+
else if (m.idadeMs > exports.SEM_BATIDA_MS) {
|
|
276
|
+
const idadeMs = m.idadeMs;
|
|
277
|
+
lacunas.push({ tipo: 'maquina.sem-batida', maquina: m.maquina, detalhe: lacunaDoCatalogo((t) => t.semBatidaHa(m.maquina, duracao(idadeMs))) });
|
|
278
|
+
}
|
|
256
279
|
}
|
|
257
280
|
return {
|
|
258
281
|
contrato: exports.CONTRATO_DO_STATUS, consultadoEm, casa: casa ? { ...casa } : null,
|
|
@@ -277,53 +300,48 @@ function textoDaRede(status) {
|
|
|
277
300
|
// escrevem. Cada VALOR vai numa linha so e sem nada que o terminal execute ou que ninguem ve, antes de
|
|
278
301
|
// entrar no texto: um `\n` num valor nao abre uma linha que parece do `ork`.
|
|
279
302
|
// X5 da revisao 6: um mapa que so troca texto (a ida e volta em JSON trocava `NaN` por `null`).
|
|
303
|
+
// RM-061 (F3b): a moldura pelo catalogo; o detalhe da lacuna (pt-BR no --json) e remontado e limpo do mesmo jeito.
|
|
280
304
|
const s = (0, saida_segura_1.valoresEmUmaLinha)(status);
|
|
305
|
+
const t = (0, locale_1.msg)().network;
|
|
281
306
|
const linhas = [];
|
|
282
307
|
const rede = s.fontes.find((f) => f.fonte === 'rede');
|
|
283
|
-
const estadoDaCasa = rede ? (rede.atualizado ?
|
|
284
|
-
linhas.push(s.casa
|
|
285
|
-
? `Orkastery Network de ${s.casa.dono} · ${s.casa.forja}: ${(0, rede_1.refDaCasa)(s.casa)} · ${estadoDaCasa}`
|
|
286
|
-
: 'Orkastery Network · sem casa: nenhuma forja com login nesta máquina');
|
|
308
|
+
const estadoDaCasa = rede ? (rede.atualizado ? t.casaLidaAgora : t.casaUltimaCopia) : t.casaNaoLida;
|
|
309
|
+
linhas.push(s.casa ? t.cabecalhoComCasa(s.casa.dono, s.casa.forja, (0, rede_1.refDaCasa)(s.casa), estadoDaCasa) : t.semCasa);
|
|
287
310
|
const consultado = [
|
|
288
|
-
...(rede ? [
|
|
289
|
-
...s.fontes.filter((f) => f.fonte === 'fabrica-estado')
|
|
290
|
-
.map((f) => `fábrica de ${f.projeto} (${f.ref}, ${f.atualizado ? 'lida agora' : 'última cópia'})`),
|
|
311
|
+
...(rede ? [t.repositorioDaRede(rede.ponta ? rede.ponta.slice(0, 7) : null)] : []),
|
|
312
|
+
...s.fontes.filter((f) => f.fonte === 'fabrica-estado').map((f) => t.fabricaDe(String(f.projeto), f.ref, f.atualizado)),
|
|
291
313
|
];
|
|
292
|
-
linhas.push(
|
|
293
|
-
linhas.push(
|
|
314
|
+
linhas.push(t.consultado(consultado.length ? consultado.join('; ') : null));
|
|
315
|
+
linhas.push(t.naoConsultado(s.naoConsultado.map(t.itemNaoConsultado).join(', ')));
|
|
294
316
|
linhas.push('');
|
|
295
317
|
if (s.membros.length === 0)
|
|
296
|
-
linhas.push(
|
|
318
|
+
linhas.push(t.nenhumaMaquina);
|
|
297
319
|
for (const m of s.membros) {
|
|
298
320
|
const esta = m.maquina !== s.estaMaquina.maquina ? ''
|
|
299
|
-
: m.origem === 'rede' && s.estaMaquina.nomeEmUso ?
|
|
300
|
-
const origem = m.origem === 'rede' ?
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
...m.forjas.map((f) => `${f.forja}: ${f.usuario ?? 'sem login'}`), m.pessoa ? `pessoa ${m.pessoa}` : null].filter(Boolean);
|
|
321
|
+
: m.origem === 'rede' && s.estaMaquina.nomeEmUso ? t.outraInstalacao : t.estaMaquina;
|
|
322
|
+
const origem = m.origem === 'rede' ? t.origemRede(m.adesao === 'fabrica') : t.origemFabrica(m.projetos.map((p) => p.nome).join(', '));
|
|
323
|
+
linhas.push(t.membro(m.maquina, esta, origem, (0, horario_1.formatarDataHora)(m.publicadoEm), duracao(m.idadeMs)));
|
|
324
|
+
const ficha = [m.hostname ? t.fichaHostname(m.hostname) : null, m.versaoOrk ? t.fichaOrk(m.versaoOrk) : null,
|
|
325
|
+
...m.forjas.map((f) => t.fichaForja(f.forja, f.usuario ?? null)), m.pessoa ? t.fichaPessoa(m.pessoa) : null].filter(Boolean);
|
|
305
326
|
if (ficha.length)
|
|
306
327
|
linhas.push(` ${ficha.join(' · ')}`);
|
|
307
328
|
if (m.runtimes.length)
|
|
308
|
-
linhas.push(
|
|
329
|
+
linhas.push(t.runtimes(m.runtimes.map((r) => `${r.runtime} ${r.versao ?? '?'}`).join(', ')));
|
|
309
330
|
if (m.hosts.length) {
|
|
310
|
-
linhas.push(
|
|
331
|
+
linhas.push(t.hosts(m.hosts.map((h) => `${h.host} ${h.versao ?? '?'}${h.adaptador ? t.hostAdaptador(h.adaptador) : ''}`).join(', ')));
|
|
311
332
|
}
|
|
312
333
|
if (m.projetos.length) {
|
|
313
|
-
linhas.push(
|
|
334
|
+
linhas.push(t.projetos(m.projetos.map((p) => `${p.nome}${p.remoto ? ` (${p.remoto})` : ''}${p.caminho ? t.projetoEm(p.caminho) : ''}`).join('; ')));
|
|
314
335
|
}
|
|
315
336
|
}
|
|
316
337
|
linhas.push('');
|
|
317
338
|
const aqui = s.estaMaquina;
|
|
318
|
-
linhas.push(aqui.membro
|
|
319
|
-
? `Esta máquina (${aqui.maquina}) é membro${aqui.adesao === 'fabrica' ? ', herdado da fábrica' : ''}${aqui.publicada ? '.' : '; o retrato dela ainda não está na casa.'}`
|
|
320
|
-
: `Esta máquina (${aqui.maquina}) não está na rede: ork network entrar.`);
|
|
339
|
+
linhas.push(aqui.membro ? t.estaEMembro(aqui.maquina, aqui.adesao === 'fabrica', aqui.publicada) : t.foraDaRedeLinha(aqui.maquina));
|
|
321
340
|
if (s.lacunas.length === 0)
|
|
322
|
-
linhas.push(
|
|
341
|
+
linhas.push(t.semLacunas);
|
|
323
342
|
else {
|
|
324
|
-
linhas.push(
|
|
325
|
-
|
|
326
|
-
linhas.push(` • ${l.tipo}: ${l.detalhe}`);
|
|
343
|
+
linhas.push(t.lacunas(s.lacunas.length));
|
|
344
|
+
s.lacunas.forEach((l, i) => linhas.push(t.lacuna(l.tipo, (0, saida_segura_1.valoresEmUmaLinha)((0, locale_1.remontar)(status.lacunas[i].detalhe)))));
|
|
327
345
|
}
|
|
328
346
|
linhas.push((0, horario_1.legendaDoFuso)());
|
|
329
347
|
return linhas.join('\n');
|
package/dist/rede.js
CHANGED
|
@@ -33,9 +33,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.RETRATO_PARADO_MS = exports.cachePronto = exports.MAXIMO_DE_ITENS = exports.refDaCasa = exports.PULSACAO_DA_REDE_MS = exports.PAINEL_DA_REDE = exports.DIR_DOS_RETRATOS = exports.BRANCH_DA_REDE = exports.CONTRATO_DO_RETRATO = void 0;
|
|
36
|
+
exports.RETRATO_PARADO_MS = exports.cachePronto = exports.MAXIMO_DE_ITENS = exports.NIVEL_MINIMO_NO_GRUPO = exports.refDaCasa = exports.PULSACAO_DA_REDE_MS = exports.PAINEL_DA_REDE = exports.DIR_DOS_RETRATOS = exports.BRANCH_DA_REDE = exports.CONTRATO_DO_RETRATO = void 0;
|
|
37
37
|
exports.nomeSeguro = nomeSeguro;
|
|
38
38
|
exports.arquivoDoRetrato = arquivoDoRetrato;
|
|
39
|
+
exports.separarRepositorio = separarRepositorio;
|
|
39
40
|
exports.resolverCasa = resolverCasa;
|
|
40
41
|
exports.hostnameSeguro = hostnameSeguro;
|
|
41
42
|
exports.retratoDaMaquina = retratoDaMaquina;
|
|
@@ -94,6 +95,7 @@ const rede_adesao_1 = require("./rede-adesao");
|
|
|
94
95
|
const rede_forja_1 = require("./rede-forja");
|
|
95
96
|
const rede_projetos_1 = require("./rede-projetos");
|
|
96
97
|
const versao_1 = require("./versao");
|
|
98
|
+
const locale_1 = require("./locale");
|
|
97
99
|
exports.CONTRATO_DO_RETRATO = 'ork.rede-maquina/v1';
|
|
98
100
|
exports.BRANCH_DA_REDE = 'main';
|
|
99
101
|
exports.DIR_DOS_RETRATOS = 'maquinas';
|
|
@@ -110,6 +112,8 @@ const BINARIO_DO_HOST = { 'claude-code': 'claude', codex: 'codex', hermes: 'herm
|
|
|
110
112
|
const VERSAO_ESTRITA = /^\d+\.\d+(?:\.\d+)?(?:[-+][0-9A-Za-z.]{1,20})?$/;
|
|
111
113
|
const refDaCasa = (c) => `${c.host}/${c.dono}/${c.repositorio}`;
|
|
112
114
|
exports.refDaCasa = refDaCasa;
|
|
115
|
+
/** O nivel minimo da pessoa no grupo para a casa da rede morar nele (GitLab: Maintainer). */
|
|
116
|
+
exports.NIVEL_MINIMO_NO_GRUPO = 40;
|
|
113
117
|
/**
|
|
114
118
|
* O nome da maquina no que vai a forja: so o que o git e a forja aceitam sem surpresa. E o mesmo no
|
|
115
119
|
* arquivo, no campo `maquina` do retrato, na trava e nos commits (S2 da revisao 2: o leitor recusava o
|
|
@@ -125,6 +129,11 @@ function nomeSeguro(maquina) {
|
|
|
125
129
|
function arquivoDoRetrato(maquina) {
|
|
126
130
|
return `${exports.DIR_DOS_RETRATOS}/${nomeSeguro(maquina)}.json`;
|
|
127
131
|
}
|
|
132
|
+
/** `--repositorio`: dono e nome pelo ULTIMO `/`, para o subgrupo do GitLab (`grupo/sub/casa`) nao ser truncado. */
|
|
133
|
+
function separarRepositorio(texto) {
|
|
134
|
+
const corte = texto?.lastIndexOf('/') ?? -1;
|
|
135
|
+
return texto && corte > 0 ? [texto.slice(0, corte), texto.slice(corte + 1)] : [null, texto ?? null];
|
|
136
|
+
}
|
|
128
137
|
/**
|
|
129
138
|
* A casa: a opcao do comando, senao a adesao gravada, senao o login da primeira forja com login.
|
|
130
139
|
* Nunca lanca: sem forja ou sem login, devolve o motivo tipado.
|
|
@@ -134,21 +143,21 @@ function resolverCasa(opcoes = {}) {
|
|
|
134
143
|
const forjas = (0, rede_forja_1.forjasDaMaquina)(amb);
|
|
135
144
|
const identidades = opcoes.identidades ?? forjas.map((f) => f.identidade());
|
|
136
145
|
const config = (0, rede_adesao_1.lerConfigDaRede)();
|
|
137
|
-
const [donoPedido, nomePedido] =
|
|
146
|
+
const [donoPedido, nomePedido] = separarRepositorio(opcoes.repositorio);
|
|
138
147
|
// B3: `--repositorio` sozinho troca so o repositorio; a forja gravada continua valendo.
|
|
139
148
|
const nomeDaForja = opcoes.forja ?? config?.forja ?? null;
|
|
140
149
|
if (!opcoes.forja && !opcoes.repositorio && config?.forja && config.dono && config.repositorio && config.host) {
|
|
141
150
|
// B9: a forja da casa e a do host gravado (GitLab proprio), nao a do ambiente de quem chamou.
|
|
142
151
|
const forja = (0, rede_forja_1.forjaPorNome)(config.forja, amb, config.host);
|
|
143
152
|
return { casa: { forja: config.forja, host: config.host, dono: config.dono, repositorio: config.repositorio, origem: 'rede.json' },
|
|
144
|
-
forja, identidades, motivo: forja ? null : { tipo: 'forja.ausente', detalhe:
|
|
153
|
+
forja, identidades, motivo: forja ? null : { tipo: 'forja.ausente', detalhe: (0, locale_1.textoDoCatalogo)((m) => m.network.cliAusente(config.forja)) } };
|
|
145
154
|
}
|
|
146
155
|
// A forja gravada vale com o host gravado (GitLab proprio), mesmo quando so o repositorio muda.
|
|
147
156
|
const daCasaGravada = nomeDaForja && config?.forja === nomeDaForja && config.host ? (0, rede_forja_1.forjaPorNome)(nomeDaForja, amb, config.host) : null;
|
|
148
157
|
const candidatas = daCasaGravada ? [daCasaGravada] : nomeDaForja ? forjas.filter((f) => f.nome === nomeDaForja) : forjas;
|
|
149
158
|
if (candidatas.length === 0) {
|
|
150
159
|
return { casa: null, forja: null, identidades, motivo: { tipo: 'forja.ausente',
|
|
151
|
-
detalhe:
|
|
160
|
+
detalhe: (0, locale_1.textoDoCatalogo)((m) => nomeDaForja ? m.network.cliAusente(nomeDaForja) : m.network.nenhumaCli) } };
|
|
152
161
|
}
|
|
153
162
|
const falhas = [];
|
|
154
163
|
for (const forja of candidatas) {
|
|
@@ -166,11 +175,13 @@ function resolverCasa(opcoes = {}) {
|
|
|
166
175
|
// Suspeitas da revisao de 03/10: prazo, erro da forja ou falta de rede no `gh api user` nao e falta de
|
|
167
176
|
// login; mandar a pessoa ao `gh auth login` esconderia o motivo de verdade.
|
|
168
177
|
if (falhas.length) {
|
|
178
|
+
// RM-061 (F3b): o montador de cada falha e guardado agora; o detalhe pode virar erro remontado depois.
|
|
179
|
+
const montarFalhas = falhas.map(locale_1.montadorDe);
|
|
169
180
|
return { casa: null, forja: null, identidades, motivo: { tipo: 'rede.sem-leitura',
|
|
170
|
-
detalhe:
|
|
181
|
+
detalhe: (0, locale_1.textoDoCatalogo)((m) => m.network.loginNaoLido(montarFalhas.map((f) => f(m)).join('; '))) } };
|
|
171
182
|
}
|
|
172
183
|
return { casa: null, forja: null, identidades, motivo: { tipo: 'forja.sem-login',
|
|
173
|
-
detalhe:
|
|
184
|
+
detalhe: (0, locale_1.textoDoCatalogo)((m) => m.network.semLogin(candidatas)) } };
|
|
174
185
|
}
|
|
175
186
|
function versaoDoAdaptador(host, home) {
|
|
176
187
|
const recibo = (0, hosts_1.lerRecibo)(path.join(home, hosts_1.HOSTS[host].destinoPadrao, hosts_1.HOSTS[host].subdir));
|
|
@@ -294,12 +305,12 @@ const CAMPOS = {
|
|
|
294
305
|
};
|
|
295
306
|
function exigirSoCampos(onde, v, permitidos) {
|
|
296
307
|
if (!v || typeof v !== 'object' || Array.isArray(v))
|
|
297
|
-
throw new
|
|
308
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.foraDoContrato(onde));
|
|
298
309
|
for (const [k, x] of Object.entries(v)) {
|
|
299
310
|
if (!permitidos.includes(k))
|
|
300
|
-
throw new
|
|
311
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.campoForaDaLista(`${onde}.${k}`));
|
|
301
312
|
if (x !== null && typeof x === 'string' && x.length > 1024)
|
|
302
|
-
throw new
|
|
313
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.campoLongo(`${onde}.${k}`));
|
|
303
314
|
}
|
|
304
315
|
}
|
|
305
316
|
/**
|
|
@@ -310,15 +321,15 @@ function exigirRetratoSeguro(r) {
|
|
|
310
321
|
exigirSoCampos('retrato', r, CAMPOS.retrato);
|
|
311
322
|
for (const lista of ['forjas', 'runtimes', 'hosts', 'projetos']) {
|
|
312
323
|
if (!Array.isArray(r[lista]))
|
|
313
|
-
throw new
|
|
324
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.foraDoContrato(lista));
|
|
314
325
|
r[lista].forEach((item, i) => exigirSoCampos(`${lista}[${i}]`, item, CAMPOS[lista]));
|
|
315
326
|
}
|
|
316
327
|
// S2 da revisao 2: o que o escritor publica, o leitor aceita; senao, ninguem ve esta maquina.
|
|
317
328
|
if (!normalizarRetrato(r))
|
|
318
|
-
throw new
|
|
329
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.contratoDoRetrato);
|
|
319
330
|
const achado = segredoNoRetrato(r);
|
|
320
331
|
if (achado)
|
|
321
|
-
throw new
|
|
332
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.segredoNoRetrato(achado.padrao, achado.onde));
|
|
322
333
|
}
|
|
323
334
|
/** O primeiro valor do retrato com cara de segredo: o padrao e o campo, nunca o valor. */
|
|
324
335
|
function segredoNoRetrato(r) {
|
|
@@ -351,7 +362,8 @@ function exigirSoOProprioRetrato(maquina, mudancas) {
|
|
|
351
362
|
const proprio = arquivoDoRetrato(maquina);
|
|
352
363
|
for (const m of mudancas) {
|
|
353
364
|
if (m.caminho !== proprio && m.caminho !== exports.PAINEL_DA_REDE) {
|
|
354
|
-
|
|
365
|
+
const caminho = m.caminho;
|
|
366
|
+
throw new locale_1.ErroDoCatalogo((t) => t.network.retratoAlheio(maquina, caminho, proprio));
|
|
355
367
|
}
|
|
356
368
|
}
|
|
357
369
|
}
|
|
@@ -440,7 +452,8 @@ function lerRetratos(cache, ponta) {
|
|
|
440
452
|
for (const arquivo of arquivos) {
|
|
441
453
|
const visivel = JSON.stringify(arquivo).slice(1, -1).slice(0, 120);
|
|
442
454
|
if (!/^maquinas\/[A-Za-z0-9._-]{1,64}\.json$/.test(arquivo)) {
|
|
443
|
-
|
|
455
|
+
// RM-061 (F3b, GO-FIX 1): o motivo nasce pelo catalogo, e a lacuna do status o remonta.
|
|
456
|
+
invalidos.push({ arquivo: visivel, motivo: (0, locale_1.textoDoCatalogo)((m) => m.network.retratoForaDoPadrao) });
|
|
444
457
|
continue;
|
|
445
458
|
}
|
|
446
459
|
let bruto;
|
|
@@ -448,12 +461,12 @@ function lerRetratos(cache, ponta) {
|
|
|
448
461
|
bruto = JSON.parse((0, branch_de_estado_1.exigirGit)(cache, ['show', `${ponta}:${arquivo}`], PREFIXO));
|
|
449
462
|
}
|
|
450
463
|
catch {
|
|
451
|
-
invalidos.push({ arquivo, motivo:
|
|
464
|
+
invalidos.push({ arquivo, motivo: (0, locale_1.textoDoCatalogo)((m) => m.network.retratoIlegivel) });
|
|
452
465
|
continue;
|
|
453
466
|
}
|
|
454
467
|
const retrato = normalizarRetrato(bruto);
|
|
455
468
|
if (!retrato) {
|
|
456
|
-
invalidos.push({ arquivo, motivo:
|
|
469
|
+
invalidos.push({ arquivo, motivo: (0, locale_1.textoDoCatalogo)((m) => m.network.retratoForaDoContrato(exports.CONTRATO_DO_RETRATO)) });
|
|
457
470
|
continue;
|
|
458
471
|
}
|
|
459
472
|
let esperado = null;
|
|
@@ -461,8 +474,9 @@ function lerRetratos(cache, ponta) {
|
|
|
461
474
|
esperado = arquivoDoRetrato(retrato.maquina);
|
|
462
475
|
}
|
|
463
476
|
catch { /* nome impossivel */ }
|
|
477
|
+
const diz = retrato.maquina;
|
|
464
478
|
if (esperado !== arquivo) {
|
|
465
|
-
invalidos.push({ arquivo, motivo:
|
|
479
|
+
invalidos.push({ arquivo, motivo: (0, locale_1.textoDoCatalogo)((m) => m.network.retratoDeOutraMaquina(diz)) });
|
|
466
480
|
continue;
|
|
467
481
|
}
|
|
468
482
|
// V9 da revisao 4: a mesma varredura do escritor; o que ela pega nao vai ao status nem ao REDE.md.
|
|
@@ -472,12 +486,14 @@ function lerRetratos(cache, ponta) {
|
|
|
472
486
|
const projetos = retrato.projetos.filter((_x, i) => !achados[i]);
|
|
473
487
|
const primeiro = achados.find((x) => x !== null);
|
|
474
488
|
if (primeiro) {
|
|
475
|
-
|
|
489
|
+
const fora = retrato.projetos.length - projetos.length, padrao = primeiro.padrao;
|
|
490
|
+
invalidos.push({ arquivo, motivo: (0, locale_1.textoDoCatalogo)((m) => m.network.retratoProjetosOmitidos(fora, padrao)) });
|
|
476
491
|
}
|
|
477
492
|
const lido = { ...retrato, projetos };
|
|
478
493
|
const segredo = segredoNoRetrato(lido);
|
|
479
494
|
if (segredo) {
|
|
480
|
-
|
|
495
|
+
const { padrao, onde } = segredo;
|
|
496
|
+
invalidos.push({ arquivo, motivo: (0, locale_1.textoDoCatalogo)((m) => m.network.retratoComSegredo(padrao, onde)) });
|
|
481
497
|
continue;
|
|
482
498
|
}
|
|
483
499
|
retratos.push(lido);
|
|
@@ -489,7 +505,9 @@ function lerRetratos(cache, ponta) {
|
|
|
489
505
|
// O cache da casa e o git sem prompt.
|
|
490
506
|
// ---------------------------------------------------------------------------
|
|
491
507
|
function dirDoCache(casa) {
|
|
492
|
-
|
|
508
|
+
const nome = `${casa.forja}-${casa.host}-${casa.dono}-${casa.repositorio}`.replace(/[^A-Za-z0-9._-]+/g, '-');
|
|
509
|
+
// O dono com subgrupo (`time/sub`) leva um resumo curto, para nao cair na pasta do dono `time-sub`; sem subgrupo, o nome de sempre.
|
|
510
|
+
return path.join((0, rede_adesao_1.pastaDaRede)(), casa.dono.includes('/') ? `${nome}-${(0, node_crypto_1.createHash)('sha256').update(casa.dono).digest('hex').slice(0, 8)}` : nome);
|
|
493
511
|
}
|
|
494
512
|
/** O cache ja foi criado? */
|
|
495
513
|
const cachePronto = (dir) => fs.existsSync(path.join(dir, '.git', 'HEAD'));
|
|
@@ -577,26 +595,45 @@ function gravarMarca(marca) {
|
|
|
577
595
|
/** A casa com o repositorio conferido: existe e e privado (D3). `criar` so no `ork network entrar`. */
|
|
578
596
|
function casaConferida(opcoes) {
|
|
579
597
|
const r = resolverCasa(opcoes);
|
|
580
|
-
if (!r.casa || !r.forja)
|
|
581
|
-
|
|
598
|
+
if (!r.casa || !r.forja) {
|
|
599
|
+
const detalhe = r.motivo ? (0, locale_1.montadorDe)(r.motivo.detalhe) : null;
|
|
600
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.semForja(detalhe === null ? null : detalhe(m)));
|
|
601
|
+
}
|
|
602
|
+
const semSuporte = r.forja.nome === 'gitlab' ? (0, rede_forja_1.gitlabSemSuporteNaRede)(opcoes.amb ?? {}, r.forja.host) : null;
|
|
603
|
+
if (semSuporte)
|
|
604
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.gitlabNaoSuportado(semSuporte));
|
|
582
605
|
let repo = r.forja.repositorio(r.casa.dono, r.casa.repositorio);
|
|
583
606
|
let criado = false;
|
|
584
607
|
if (!repo.existe) {
|
|
608
|
+
const ref = (0, exports.refDaCasa)(r.casa);
|
|
585
609
|
if (!opcoes.criar)
|
|
586
|
-
throw new
|
|
610
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.semRepositorio(ref));
|
|
587
611
|
const login = (r.identidades.find((i) => i.forja === r.forja.nome && i.host === r.forja.host) ?? r.forja.identidade()).usuario;
|
|
612
|
+
let namespaceId;
|
|
588
613
|
if (r.casa.dono !== login) {
|
|
589
|
-
|
|
614
|
+
// Outro dono so vale quando e um grupo em que a pessoa e Maintainer ou acima; forja sem a capacidade recusa como antes.
|
|
615
|
+
const dono = r.forja.donoDaRede?.(r.casa.dono) ?? null;
|
|
616
|
+
if (dono && !dono.ok && dono.erro.codigo !== 'forja.nao-achei') {
|
|
617
|
+
const erro = dono.erro, cli = r.forja.cli, tipo = r.forja.nome, rota = `namespaces/${r.casa.dono}`;
|
|
618
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.apiFalhou(cli, rota, m.forja.motivo(erro, tipo)));
|
|
619
|
+
}
|
|
620
|
+
if (!dono || !dono.ok || dono.valor.tipo !== 'grupo')
|
|
621
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.repositorioAlheio(ref, login));
|
|
622
|
+
const nivel = dono.valor.nivel ?? 0, grupo = dono.valor.caminho;
|
|
623
|
+
if (nivel < exports.NIVEL_MINIMO_NO_GRUPO)
|
|
624
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.grupoSemNivel(ref, grupo, login, nivel));
|
|
625
|
+
namespaceId = dono.valor.namespaceId;
|
|
590
626
|
}
|
|
591
|
-
repo = r.forja.criarPrivado(r.casa.repositorio, DESCRICAO);
|
|
627
|
+
repo = r.forja.criarPrivado(r.casa.repositorio, DESCRICAO, r.casa.dono, namespaceId);
|
|
592
628
|
criado = true;
|
|
593
629
|
}
|
|
630
|
+
const refDaConferida = (0, exports.refDaCasa)(r.casa), cli = r.forja.cli;
|
|
594
631
|
if (repo.privado !== true)
|
|
595
|
-
throw new
|
|
632
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.repositorioPublico(refDaConferida));
|
|
596
633
|
if (!repo.url)
|
|
597
|
-
throw new
|
|
634
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.semUrl(cli, refDaConferida));
|
|
598
635
|
if (!urlDaCasaAceita(repo.url)) {
|
|
599
|
-
throw new
|
|
636
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.semHttps(cli, refDaConferida));
|
|
600
637
|
}
|
|
601
638
|
return { casa: r.casa, forja: r.forja, url: repo.url, criado, identidades: r.identidades };
|
|
602
639
|
}
|
|
@@ -735,13 +772,13 @@ function gravarNaCasa(conferida, retrato, descartados, opcoes) {
|
|
|
735
772
|
return { acao: 'ocupado', maquina, casa: (0, exports.refDaCasa)(casa), commit: null, tentativas: 0, descartados };
|
|
736
773
|
try {
|
|
737
774
|
if (opcoes.exigirAdesao && !(0, rede_adesao_1.adesaoDaRede)().membro)
|
|
738
|
-
throw new
|
|
775
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.saiuDaRede);
|
|
739
776
|
const cache = prepararCache(casa, url, forja.helperDeCredencial(), maquina);
|
|
740
777
|
const assinatura = assinaturaDoRetrato(retrato);
|
|
741
778
|
for (let tentativa = 1; tentativa <= TENTATIVAS; tentativa++) {
|
|
742
779
|
const { ponta, atualizado } = (0, rede_forja_1.comGitIsolado)(() => (0, branch_de_estado_1.buscarBranch)(cache, 'origin', exports.BRANCH_DA_REDE, PREFIXO, 30000));
|
|
743
780
|
if (!atualizado)
|
|
744
|
-
throw new
|
|
781
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.semLeitura((0, exports.refDaCasa)(casa)));
|
|
745
782
|
const { retratos } = retratosDaPonta(cache, ponta);
|
|
746
783
|
const atual = retratos.find((r) => r.maquina === maquina);
|
|
747
784
|
// U2: o arquivo que esta versao nao le ainda pode ser de outra instalacao (contrato mais novo).
|
|
@@ -749,12 +786,9 @@ function gravarNaCasa(conferida, retrato, descartados, opcoes) {
|
|
|
749
786
|
const alheio = !!idDoOutro && idDoOutro !== retrato.id;
|
|
750
787
|
if (alheio && !opcoes.tomarNome) {
|
|
751
788
|
// U7 da revisao 3: o hostname igual sugere a propria maquina, mas duas VMs podem se chamar `ubuntu`.
|
|
752
|
-
const
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
: '; escolha outro nome com ork network entrar --maquina NOME, ou tome este com --forcar';
|
|
756
|
-
const quem = atual ? ` (hostname ${atual.hostname}, batida ${(0, horario_1.formatarDataHora)(atual.publicadoEm)})` : ' (num retrato que esta versao nao le)';
|
|
757
|
-
throw new Error(`rede.nome-em-uso: outra instalacao ja publica como "${maquina}"${quem}${dica}`);
|
|
789
|
+
const mesmoHostname = atual?.hostname === hostnameSeguro();
|
|
790
|
+
const outro = atual ? { hostname: atual.hostname, publicadoEm: atual.publicadoEm } : null;
|
|
791
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.nomeEmUso(maquina, outro ? m.network.quemHostname(String(outro.hostname), (0, horario_1.formatarDataHora)(outro.publicadoEm)) : m.network.quemIlegivel, mesmoHostname ? m.network.dicaMesmoHostname : m.network.dicaOutroNome));
|
|
758
792
|
}
|
|
759
793
|
const mudancas = [
|
|
760
794
|
{ caminho: arquivoDoRetrato(maquina), conteudo: JSON.stringify(retrato, null, 2) + '\n' },
|
|
@@ -769,7 +803,7 @@ function gravarNaCasa(conferida, retrato, descartados, opcoes) {
|
|
|
769
803
|
return { acao: 'publicou', maquina, casa: (0, exports.refDaCasa)(casa), commit, tentativas: tentativa, descartados, ...(alheio ? { tomouNome: true } : {}) };
|
|
770
804
|
}
|
|
771
805
|
}
|
|
772
|
-
throw new
|
|
806
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.concorrencia(TENTATIVAS));
|
|
773
807
|
}
|
|
774
808
|
finally {
|
|
775
809
|
trava.liberar();
|
|
@@ -783,7 +817,7 @@ function gravarNaCasa(conferida, retrato, descartados, opcoes) {
|
|
|
783
817
|
function publicarRede(opcoes = {}) {
|
|
784
818
|
const adesao = (0, rede_adesao_1.adesaoDaRede)();
|
|
785
819
|
if (!adesao.membro)
|
|
786
|
-
throw new
|
|
820
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.foraDaRede);
|
|
787
821
|
const amb = opcoes.amb ?? {};
|
|
788
822
|
const maquina = nomeSeguro((0, maquina_1.nomeDaMaquina)(opcoes.maquina));
|
|
789
823
|
const id = (0, rede_adesao_1.idDaMaquina)();
|
|
@@ -833,7 +867,7 @@ function entrarNaRede(opcoes = {}) {
|
|
|
833
867
|
const explicito = (opcoes.maquina ?? '').trim();
|
|
834
868
|
const maquina = explicito || nomeSeguro((0, maquina_1.lerConfigDaMaquina)()?.nome || (0, maquina_1.nomeDaMaquina)());
|
|
835
869
|
if (!NOME_DE_MAQUINA.test(maquina)) {
|
|
836
|
-
throw new
|
|
870
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.nomeInvalido(maquina));
|
|
837
871
|
}
|
|
838
872
|
const amb = opcoes.amb ?? {};
|
|
839
873
|
const lidas = opcoes.identidades ?? (0, rede_forja_1.forjasDaMaquina)(amb).map((f) => f.identidade());
|
|
@@ -847,7 +881,8 @@ function entrarNaRede(opcoes = {}) {
|
|
|
847
881
|
exigirRetratoSeguro(retrato);
|
|
848
882
|
const publicacao = gravarNaCasa(conferida, retrato, descartados, { exigirAdesao: false, tomarNome: opcoes.tomarNome });
|
|
849
883
|
if (publicacao.acao === 'ocupado') {
|
|
850
|
-
|
|
884
|
+
const trava = TRAVA();
|
|
885
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.ocupadoAoEntrar(trava));
|
|
851
886
|
}
|
|
852
887
|
(0, maquina_1.gravarConfigDaMaquina)({ nome: maquina });
|
|
853
888
|
const { casa } = conferida;
|
|
@@ -875,11 +910,14 @@ function sairDaRede(opcoes = {}) {
|
|
|
875
910
|
if (!repo.existe || !repo.url)
|
|
876
911
|
return { maquina, casa: (0, exports.refDaCasa)(r.casa), commit: null, alheio: false };
|
|
877
912
|
if (!urlDaCasaAceita(repo.url)) {
|
|
878
|
-
|
|
913
|
+
const cli = r.forja.cli, ref = (0, exports.refDaCasa)(r.casa);
|
|
914
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.semHttpsAoSair(cli, ref));
|
|
879
915
|
}
|
|
880
916
|
const trava = travarCasa(30000);
|
|
881
|
-
if (!trava.ok)
|
|
882
|
-
|
|
917
|
+
if (!trava.ok) {
|
|
918
|
+
const qual = TRAVA();
|
|
919
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.ocupadoAoSair(qual));
|
|
920
|
+
}
|
|
883
921
|
try {
|
|
884
922
|
// Suspeitas da revisao de 03/10: a publicacao que ja segurava a trava quando o `sair` comecou grava
|
|
885
923
|
// a marca ao terminar o push. Sob a trava ela ja terminou, e a proxima reconfere a adesao e recusa
|
|
@@ -893,8 +931,10 @@ function sairDaRede(opcoes = {}) {
|
|
|
893
931
|
const id = (0, rede_adesao_1.idDaMaquina)();
|
|
894
932
|
for (let tentativa = 1; tentativa <= TENTATIVAS; tentativa++) {
|
|
895
933
|
const { ponta, atualizado } = (0, rede_forja_1.comGitIsolado)(() => (0, branch_de_estado_1.buscarBranch)(cache, 'origin', exports.BRANCH_DA_REDE, PREFIXO, 30000));
|
|
896
|
-
if (!atualizado)
|
|
897
|
-
|
|
934
|
+
if (!atualizado) {
|
|
935
|
+
const ref = (0, exports.refDaCasa)(r.casa);
|
|
936
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.semLeituraAoSair(ref));
|
|
937
|
+
}
|
|
898
938
|
const { retratos, invalidos } = retratosDaPonta(cache, ponta);
|
|
899
939
|
const atual = retratos.find((x) => x.maquina === maquina);
|
|
900
940
|
// S9 da revisao 2: o arquivo com o nome desta maquina sai tambem quando esta invalido; so o de
|
|
@@ -918,7 +958,7 @@ function sairDaRede(opcoes = {}) {
|
|
|
918
958
|
if (commit)
|
|
919
959
|
return { maquina, casa: (0, exports.refDaCasa)(r.casa), commit, alheio: false };
|
|
920
960
|
}
|
|
921
|
-
throw new
|
|
961
|
+
throw new locale_1.ErroDoCatalogo((m) => m.network.concorrencia(TENTATIVAS));
|
|
922
962
|
}
|
|
923
963
|
finally {
|
|
924
964
|
trava.liberar();
|