@orkastery/cli 0.5.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/README.md +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 +118 -4
- 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/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 +16 -8
- 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 +500 -0
- package/dist/check-modo.js +41 -0
- package/dist/check-paralelo.js +183 -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 +84 -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 +81 -74
- package/dist/doctor-forja.js +345 -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 +143 -43
- 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 +13 -10
- 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 +16 -0
- package/dist/hosts.js +104 -134
- package/dist/index.js +848 -548
- package/dist/indice-vetorial.js +14 -12
- package/dist/init.js +11 -2
- package/dist/integracoes-locais.js +2 -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 +220 -0
- package/dist/locale-adapter.js +291 -0
- package/dist/locale-ajuda.js +76 -4
- 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 +290 -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 +145 -6
- package/dist/locale-security-scan.js +69 -0
- package/dist/locale-setup.js +192 -0
- package/dist/locale-ship.js +169 -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 +287 -11
- 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 +73 -8
- package/dist/mcp-noctum.js +101 -0
- package/dist/mcp-server.js +82 -14
- 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/modos-migracao.js +8 -6
- package/dist/modos.js +17 -18
- package/dist/network-roadmap.js +85 -49
- package/dist/noctum-aceite.js +789 -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 +482 -0
- package/dist/noctum-coordenacao.js +1225 -0
- package/dist/noctum-entrega.js +1169 -0
- package/dist/noctum-envelope.js +252 -16
- package/dist/noctum-execucao.js +95 -23
- package/dist/noctum-fechamento.js +405 -0
- package/dist/noctum-fila.js +43 -9
- package/dist/noctum-guarda.js +256 -0
- package/dist/noctum-integracao.js +507 -0
- package/dist/noctum-maquinas.js +383 -0
- package/dist/noctum-medicao.js +450 -0
- package/dist/noctum-modo.js +362 -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 +591 -0
- package/dist/noctum-registro.js +215 -0
- package/dist/noctum-relatorio.js +827 -0
- package/dist/noctum-resposta.js +207 -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 +639 -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 +146 -124
- package/dist/phase.js +53 -27
- package/dist/policies.js +33 -0
- package/dist/postura-local.js +4 -3
- 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 +12 -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 +228 -73
- package/dist/roadmap-reservas.js +32 -32
- package/dist/runtime-ambiente.js +5 -0
- package/dist/runtime-context.js +117 -43
- package/dist/runtime-escada.js +423 -0
- package/dist/runtime-profiles.js +103 -46
- package/dist/saida-segura.js +3 -2
- package/dist/security-scan/agil.js +355 -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 +188 -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.js +156 -10
- package/dist/sessoes-contas.js +9 -0
- package/dist/sessoes-inventario.js +1 -1
- package/dist/sessoes.js +25 -23
- package/dist/setup.js +59 -58
- 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 +507 -0
- package/dist/verify.js +472 -29
- 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 +9 -4
- 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
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.REMOTO_DA_FORJA = void 0;
|
|
37
|
+
exports.sondasPadraoDoDoctor = sondasPadraoDoDoctor;
|
|
38
|
+
exports.checarForja = checarForja;
|
|
39
|
+
/**
|
|
40
|
+
* A secao "forja" do `ork doctor`: a forja resolvida do remoto `origin` e de onde veio cada valor, o alcance das
|
|
41
|
+
* portas HTTPS e SSH, a cadeia TLS, o subcaminho, a CLI e o login, os escopos do token, a versao do servidor, as
|
|
42
|
+
* opcoes de merge do projeto e as capacidades do adaptador.
|
|
43
|
+
*
|
|
44
|
+
* Sem remoto com host de forja e sem o bloco `forja:`, a secao nao se aplica e nao tem linha. Cada linha encerra as
|
|
45
|
+
* que dependem dela (sem HTTPS nao ha TLS; sem login nao ha API). So reprova o que a forja impede de verdade, e so
|
|
46
|
+
* quando o projeto depende dela (`ci.required_for_ship` ou o bloco `forja:`); fora disso, o mesmo achado e aviso: o
|
|
47
|
+
* doctor e gate de despacho. So consulta: nada e escrito na forja. A rede e a CLI sao injetaveis.
|
|
48
|
+
*/
|
|
49
|
+
const node_child_process_1 = require("node:child_process");
|
|
50
|
+
const fs = __importStar(require("node:fs"));
|
|
51
|
+
const os = __importStar(require("node:os"));
|
|
52
|
+
const zod_1 = require("zod");
|
|
53
|
+
const adaptador_1 = require("./forja/adaptador");
|
|
54
|
+
const api_1 = require("./forja/api");
|
|
55
|
+
const cli_1 = require("./forja/cli");
|
|
56
|
+
const registro_1 = require("./forja/registro");
|
|
57
|
+
const versao_1 = require("./forja/versao");
|
|
58
|
+
const endereco_1 = require("./forja/endereco");
|
|
59
|
+
const executor_1 = require("./forja/executor");
|
|
60
|
+
const cache_1 = require("./forja/cache");
|
|
61
|
+
const resolver_1 = require("./forja/resolver");
|
|
62
|
+
const locale_1 = require("./locale");
|
|
63
|
+
const pedidos_1 = require("./forja/gitlab/pedidos");
|
|
64
|
+
const mcp_ship_transporte_1 = require("./mcp-ship-transporte");
|
|
65
|
+
const util_1 = require("./util");
|
|
66
|
+
/** O remoto conferido: o mesmo que a CI do `ork ship` consulta por padrao. */
|
|
67
|
+
exports.REMOTO_DA_FORJA = 'origin';
|
|
68
|
+
const PRAZO_DA_REDE_MS = 5_000;
|
|
69
|
+
/** Um processo filho do Node mede a porta ou a cadeia TLS e devolve JSON: o doctor e sincrono. */
|
|
70
|
+
const SCRIPT_DA_REDE = [
|
|
71
|
+
"const net = require('node:net'), tls = require('node:tls'), fs = require('node:fs');",
|
|
72
|
+
'const [modo, host, porta, prazo, ca] = process.argv.slice(1);',
|
|
73
|
+
'const fim = (r) => { process.stdout.write(JSON.stringify(r)); process.exit(0); };',
|
|
74
|
+
"setTimeout(() => fim(modo === 'tcp' ? { estado: 'sem-resposta' } : { ok: false, motivo: 'sem-resposta' }), Number(prazo));",
|
|
75
|
+
"if (modo === 'tcp') {",
|
|
76
|
+
' const s = net.connect({ host, port: Number(porta) });',
|
|
77
|
+
" s.on('connect', () => { s.destroy(); fim({ estado: 'aberta' }); });",
|
|
78
|
+
" s.on('error', (e) => fim({ estado: e.code === 'ECONNREFUSED' ? 'recusada' : 'sem-resposta' }));",
|
|
79
|
+
'} else {',
|
|
80
|
+
' const o = { host, port: Number(porta), rejectUnauthorized: true };',
|
|
81
|
+
' if (!net.isIP(host)) o.servername = host;',
|
|
82
|
+
' if (ca) o.ca = fs.readFileSync(ca);',
|
|
83
|
+
' const s = tls.connect(o);',
|
|
84
|
+
" s.on('secureConnect', () => { s.destroy(); fim({ ok: true }); });",
|
|
85
|
+
" s.on('error', (e) => fim({ ok: false, motivo: e.code || 'erro' }));",
|
|
86
|
+
'}',
|
|
87
|
+
].join('\n');
|
|
88
|
+
function sondarRede(argv, prazoMs) {
|
|
89
|
+
const r = (0, node_child_process_1.spawnSync)(process.execPath, ['-e', SCRIPT_DA_REDE, ...argv], { encoding: 'utf8', timeout: prazoMs + 2_000, maxBuffer: 64 * 1024 });
|
|
90
|
+
try {
|
|
91
|
+
const j = JSON.parse(r.stdout);
|
|
92
|
+
return j && typeof j === 'object' ? j : {};
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function sondasPadraoDoDoctor(raiz) {
|
|
99
|
+
return {
|
|
100
|
+
urlDoRemoto: (dir, remoto) => {
|
|
101
|
+
const r = (0, util_1.exec)('git', ['remote', 'get-url', '--', remoto], dir, 10_000);
|
|
102
|
+
return r.ok ? r.stdout.trim() : null;
|
|
103
|
+
},
|
|
104
|
+
sondas: resolver_1.SONDAS_PADRAO,
|
|
105
|
+
porta: (host, porta, prazoMs) => {
|
|
106
|
+
const e = sondarRede(['tcp', host, String(porta), String(prazoMs), ''], prazoMs).estado;
|
|
107
|
+
return e === 'aberta' || e === 'recusada' ? e : 'sem-resposta';
|
|
108
|
+
},
|
|
109
|
+
tls: (host, porta, ca, prazoMs) => {
|
|
110
|
+
const r = sondarRede(['tls', host, String(porta), String(prazoMs), ca ?? ''], prazoMs);
|
|
111
|
+
return r.ok === true ? { ok: true } : { ok: false, motivo: typeof r.motivo === 'string' ? r.motivo : 'sem-resposta' };
|
|
112
|
+
},
|
|
113
|
+
rodar: executor_1.rodarCli,
|
|
114
|
+
agoraMs: () => Date.now(),
|
|
115
|
+
cache: (0, cache_1.dirDoCacheDaForja)(raiz),
|
|
116
|
+
plataforma: process.platform,
|
|
117
|
+
transporteDoShip: (dir) => { try {
|
|
118
|
+
return (0, mcp_ship_transporte_1.fixacaoInstalada)(dir)?.transporte ?? null;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return null;
|
|
122
|
+
} },
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const legivel = (arquivo) => {
|
|
126
|
+
try {
|
|
127
|
+
fs.accessSync(arquivo, fs.constants.R_OK);
|
|
128
|
+
return fs.statSync(arquivo).isFile();
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
function identidade(f, porta) {
|
|
135
|
+
const m = (0, locale_1.msg)().forja.doctor;
|
|
136
|
+
const o = (x) => m.origens[x] ?? x;
|
|
137
|
+
return m.identidade(f.tipo, f.host, porta, f.caminhoBase || '/', f.repo, m.origensDosCampos(o(f.origem.tipo), o(f.origem.host), o(f.origem.porta), o(f.origem.caminhoBase)));
|
|
138
|
+
}
|
|
139
|
+
/** Alcance e TLS; `false` quando o que vem depois nao tem como rodar. */
|
|
140
|
+
function alcanceETls(f, portaWeb, http, s, linha, checks) {
|
|
141
|
+
const m = (0, locale_1.msg)().forja.doctor;
|
|
142
|
+
const sshHost = f.sshHost ?? f.host, sshPorta = f.sshPorta ?? 22;
|
|
143
|
+
const web = s.porta(f.host, portaWeb, PRAZO_DA_REDE_MS), ssh = s.porta(sshHost, sshPorta, PRAZO_DA_REDE_MS);
|
|
144
|
+
const detalhe = m.alcance(m.alcanceDe(f.host, portaWeb, m.portas[web]), m.alcanceDe(sshHost, sshPorta, m.portas[ssh]));
|
|
145
|
+
if (web !== 'aberta') {
|
|
146
|
+
checks.push(linha('forja alcance', 'fail', detalhe, m.webForaCorrecao(f.host, portaWeb)));
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
checks.push(linha('forja alcance', ssh === 'aberta' ? 'ok' : 'warn', detalhe, m.sshForaCorrecao));
|
|
150
|
+
if (http) {
|
|
151
|
+
checks.push(linha('forja tls', 'warn', m.tlsHttp(f.host), m.tlsHttpCorrecao));
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
if (f.ca && !legivel(f.ca)) {
|
|
155
|
+
checks.push(linha('forja tls', 'fail', m.caAusente(f.ca), m.caAusenteCorrecao));
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
const tls = s.tls(f.host, portaWeb, f.ca, PRAZO_DA_REDE_MS);
|
|
159
|
+
if (!tls.ok) {
|
|
160
|
+
checks.push(linha('forja tls', 'fail', m.tlsFalhou(f.host, tls.motivo), m.tlsCorrecao));
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
// O gh le a CA do manifesto por SSL_CERT_FILE, e o Go so o le no Linux.
|
|
164
|
+
if (f.tipo === 'github' && f.ca && s.plataforma !== 'linux') {
|
|
165
|
+
checks.push(linha('forja tls', 'warn', m.tlsCaForaDoLinux(f.host, f.ca), m.tlsCaForaDoLinuxCorrecao));
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
checks.push(linha('forja tls', 'ok', m.tlsOk(f.host, f.ca)));
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
const PRAZO_DA_CLI_MS = 10_000;
|
|
172
|
+
function cliELogin(f, http, s, linha, checks) {
|
|
173
|
+
const m = (0, locale_1.msg)().forja.doctor, cli = cli_1.CLI_DA_FORJA[f.tipo];
|
|
174
|
+
const correcao = m.cliCorrecao(cli.cmd, cli.minima);
|
|
175
|
+
const v = s.rodar({ cmd: cli.cmd, args: ['--version'], prazoMs: PRAZO_DA_CLI_MS, maxBuffer: 1024 * 1024, cwd: os.tmpdir(), reduzido: true });
|
|
176
|
+
if (v.erro === 'ENOENT') {
|
|
177
|
+
checks.push(linha('forja cli', 'fail', m.cliAusente(cli.cmd, cli.minima), correcao));
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
const versao = cli.lerVersao(`${v.stdout}\n${v.stderr}`);
|
|
181
|
+
if (!versao) {
|
|
182
|
+
checks.push(linha('forja cli', 'fail', m.cliIlegivel(cli.cmd), correcao));
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
if ((0, cli_1.versaoAbaixo)(versao, cli.minima)) {
|
|
186
|
+
checks.push(linha('forja cli', 'fail', m.cliAbaixo(cli.cmd, versao, cli.minima), correcao));
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
checks.push(linha('forja cli', 'ok', m.cli(cli.cmd, versao, cli.minima)));
|
|
190
|
+
const alvo = `${(0, cli_1.hostDaApi)(f)}${f.caminhoBase}`;
|
|
191
|
+
if (!(0, api_1.temLogin)(f, s.rodar)) {
|
|
192
|
+
// O comando que a pessoa roda: com o caminho base no glab (guardado como host, com subfolder) e o token pelo stdin.
|
|
193
|
+
checks.push(linha('forja login', 'fail', m.semLogin(cli.cmd, alvo), m.loginCorrecao(cli.entrar(f, http).join(' '))));
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
checks.push(linha('forja login', 'ok', m.login(cli.cmd, alvo)));
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
/** O subcaminho (com caminho base) e o servidor, pela mesma leitura do metadata. */
|
|
200
|
+
function servidor(f, s, api, linha, checks) {
|
|
201
|
+
const m = (0, locale_1.msg)().forja.doctor;
|
|
202
|
+
const meta = (0, versao_1.lerMetadados)(f, { cache: s.cache, agoraMs: s.agoraMs(), api });
|
|
203
|
+
if (f.caminhoBase) {
|
|
204
|
+
checks.push(meta.ok ? linha('forja subcaminho', 'ok', m.subcaminho(f.caminhoBase))
|
|
205
|
+
: linha('forja subcaminho', 'fail', m.subcaminhoFalhou(f.caminhoBase, (0, locale_1.msg)().forja.motivo(meta.erro, f.tipo)), m.subcaminhoCorrecao));
|
|
206
|
+
}
|
|
207
|
+
if (!meta.ok) {
|
|
208
|
+
if (!f.caminhoBase)
|
|
209
|
+
checks.push(linha('forja servidor', 'fail', m.servidorFalhou((0, locale_1.msg)().forja.motivo(meta.erro, f.tipo)), m.servidorFalhouCorrecao));
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const v = meta.valor;
|
|
213
|
+
const cache = v.doCache ? `; ${m.doCache}` : '';
|
|
214
|
+
const piso = versao_1.FAIXAS[f.tipo]?.piso;
|
|
215
|
+
// A versao ilegivel na forja com faixas (`sem-faixa`) nao prova o piso: reprova como abaixo dele.
|
|
216
|
+
if ((v.faixa === 'abaixo-do-piso' || v.faixa === 'sem-faixa') && piso) {
|
|
217
|
+
checks.push(linha('forja servidor', 'fail', m.servidorAbaixo(v.versao ?? '?', piso) + cache, m.servidorCorrecao(piso)));
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
checks.push(linha('forja servidor', 'ok', (versao_1.FAIXAS[f.tipo]
|
|
221
|
+
? m.servidor(v.versao ?? '?', (v.edicao ?? '?').toUpperCase(), m.faixas[v.faixa] ?? v.faixa)
|
|
222
|
+
: m.servidorSemFaixa(f.host, v.versao)) + cache));
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
const TOKEN_DO_GITLAB = zod_1.z.object({ scopes: zod_1.z.array(zod_1.z.string()) });
|
|
226
|
+
/** `empurra`: o SHIP do MCP empurra pelo `forja-https`, com o token da CLI; no GitLab, ele precisa de escrita no repositorio. */
|
|
227
|
+
function escopo(f, api, linha, empurra = false) {
|
|
228
|
+
const m = (0, locale_1.msg)().forja.doctor;
|
|
229
|
+
const naoMedivel = (motivo) => linha('forja escopo', 'warn', m.escopoNaoMedivel(motivo), m.escopoNaoMedivelCorrecao);
|
|
230
|
+
if (f.tipo === 'gitlab') {
|
|
231
|
+
const r = api({ metodo: 'GET', caminho: 'personal_access_tokens/self' });
|
|
232
|
+
if (!r.ok)
|
|
233
|
+
return naoMedivel((0, locale_1.msg)().forja.motivo(r.erro, f.tipo));
|
|
234
|
+
const lido = TOKEN_DO_GITLAB.safeParse(r.valor.corpo);
|
|
235
|
+
if (!lido.success)
|
|
236
|
+
return naoMedivel('personal_access_tokens/self');
|
|
237
|
+
const lista = lido.data.scopes.join(', ') || m.nenhum;
|
|
238
|
+
if (!lido.data.scopes.some((x) => x === 'api' || x === 'read_api'))
|
|
239
|
+
return linha('forja escopo', 'fail', m.escopoSemLeitura(lista), m.escopoCorrecao);
|
|
240
|
+
if (empurra && !lido.data.scopes.some((x) => x === 'api' || x === 'write_repository')) {
|
|
241
|
+
return linha('forja escopo', 'fail', m.escopoSemEscrita(lista), m.escopoSemEscritaCorrecao);
|
|
242
|
+
}
|
|
243
|
+
return linha('forja escopo', 'ok', m.escopo(lista));
|
|
244
|
+
}
|
|
245
|
+
if (f.tipo === 'github') {
|
|
246
|
+
// `rate_limit` nao gasta a cota e traz o `x-oauth-scopes` do token classico.
|
|
247
|
+
const r = api({ metodo: 'GET', caminho: 'rate_limit' });
|
|
248
|
+
if (!r.ok)
|
|
249
|
+
return naoMedivel((0, locale_1.msg)().forja.motivo(r.erro, f.tipo));
|
|
250
|
+
const cabecalho = r.valor.cabecalhos['x-oauth-scopes'];
|
|
251
|
+
if (cabecalho === undefined)
|
|
252
|
+
return linha('forja escopo', 'ok', m.escopoFineGrained);
|
|
253
|
+
const escopos = cabecalho.split(',').map((x) => x.trim()).filter(Boolean);
|
|
254
|
+
const lista = escopos.join(', ') || m.nenhum;
|
|
255
|
+
return escopos.includes('repo') ? linha('forja escopo', 'ok', m.escopo(lista)) : linha('forja escopo', 'warn', m.escopoSemRepo(lista), m.escopoSemRepoCorrecao);
|
|
256
|
+
}
|
|
257
|
+
return linha('forja escopo', 'ok', m.escopoNaoMedivel(f.tipo));
|
|
258
|
+
}
|
|
259
|
+
const PROJETO_DO_GITLAB = zod_1.z.object({
|
|
260
|
+
merge_method: zod_1.z.string(), squash_option: zod_1.z.string().optional(), merge_commit_template: zod_1.z.string().nullable().optional(),
|
|
261
|
+
merge_pipelines_enabled: zod_1.z.boolean().optional(), merge_trains_enabled: zod_1.z.boolean().optional(),
|
|
262
|
+
});
|
|
263
|
+
const REPOSITORIO_DO_GITHUB = zod_1.z.object({
|
|
264
|
+
allow_merge_commit: zod_1.z.boolean().optional(), allow_squash_merge: zod_1.z.boolean().optional(), allow_rebase_merge: zod_1.z.boolean().optional(),
|
|
265
|
+
});
|
|
266
|
+
/** O metodo de merge e o resto do que decide se o merge `ship(<thread>)` chega a base. So avisa; o projeto nao lido reprova. */
|
|
267
|
+
function projetoDaForja(f, api, linha) {
|
|
268
|
+
const m = (0, locale_1.msg)().forja.doctor;
|
|
269
|
+
const caminho = f.tipo === 'gitlab' ? (0, pedidos_1.projetoNaApi)(f.repo) : `repos/${f.repo}`;
|
|
270
|
+
if (f.tipo !== 'gitlab' && f.tipo !== 'github')
|
|
271
|
+
return linha('forja projeto', 'ok', m.naoMedivel);
|
|
272
|
+
const r = api({ metodo: 'GET', caminho });
|
|
273
|
+
if (!r.ok)
|
|
274
|
+
return linha('forja projeto', 'fail', m.projetoFalhou(f.repo, (0, locale_1.msg)().forja.motivo(r.erro, f.tipo)), m.projetoFalhouCorrecao);
|
|
275
|
+
const invalido = () => linha('forja projeto', 'warn', m.projetoFalhou(f.repo, (0, locale_1.msg)().forja.motivo({ codigo: 'forja.resposta-invalida', detalhe: caminho }, f.tipo)), m.projetoFalhouCorrecao);
|
|
276
|
+
if (f.tipo === 'gitlab') {
|
|
277
|
+
const lido = PROJETO_DO_GITLAB.safeParse(r.valor.corpo);
|
|
278
|
+
if (!lido.success)
|
|
279
|
+
return invalido();
|
|
280
|
+
const p = lido.data;
|
|
281
|
+
const estado = (v) => (v === undefined ? m.naoDisponivel : v ? m.ligado : m.desligado);
|
|
282
|
+
const avisos = [];
|
|
283
|
+
if (p.merge_method === 'ff')
|
|
284
|
+
avisos.push(m.avisoFf);
|
|
285
|
+
else if (!(p.merge_commit_template ?? '').trimStart().startsWith('%{title}'))
|
|
286
|
+
avisos.push(m.avisoMensagemPadrao);
|
|
287
|
+
if (p.squash_option === 'always' || p.squash_option === 'default_on')
|
|
288
|
+
avisos.push(m.avisoSquash(p.squash_option));
|
|
289
|
+
const detalhe = [m.projetoGitlab(p.merge_method, p.squash_option ?? '?', estado(p.merge_pipelines_enabled), estado(p.merge_trains_enabled)),
|
|
290
|
+
...avisos].join('; ');
|
|
291
|
+
return linha('forja projeto', avisos.length ? 'warn' : 'ok', detalhe, m.projetoGitlabCorrecao);
|
|
292
|
+
}
|
|
293
|
+
const lido = REPOSITORIO_DO_GITHUB.safeParse(r.valor.corpo);
|
|
294
|
+
if (!lido.success)
|
|
295
|
+
return invalido();
|
|
296
|
+
const p = lido.data;
|
|
297
|
+
const permite = (v) => (v === undefined ? m.naoMedivel : v ? m.permitido : m.desligado);
|
|
298
|
+
const avisos = p.allow_merge_commit === false ? [m.avisoSemMergeCommit] : [];
|
|
299
|
+
const detalhe = [m.projetoGithub(permite(p.allow_merge_commit), permite(p.allow_squash_merge), permite(p.allow_rebase_merge)), ...avisos].join('; ');
|
|
300
|
+
return linha('forja projeto', avisos.length ? 'warn' : 'ok', detalhe, m.projetoGithubCorrecao);
|
|
301
|
+
}
|
|
302
|
+
function capacidades(f) {
|
|
303
|
+
const m = (0, locale_1.msg)().forja.doctor, a = (0, registro_1.adaptadorDaForja)(f.tipo);
|
|
304
|
+
// O `checksNoCommit` e o caminho antigo do executor do `gh`: a forja que le a CI pelo `estadoDeCi` nao precisa dele.
|
|
305
|
+
const mostradas = adaptador_1.CAPACIDADES.filter((c) => c !== 'checksNoCommit' || typeof a.checksNoCommit === 'function' || typeof a.estadoDeCi !== 'function');
|
|
306
|
+
const ligadas = mostradas.filter((c) => typeof a[c] === 'function');
|
|
307
|
+
const desligadas = mostradas.filter((c) => typeof a[c] !== 'function');
|
|
308
|
+
return desligadas.length
|
|
309
|
+
? { nome: 'forja capacidades', nivel: 'warn', detalhe: m.capacidadesDesligadas(ligadas.join(', ') || m.nenhum, desligadas.join(', ')),
|
|
310
|
+
correcao: m.capacidadesCorrecao }
|
|
311
|
+
: { nome: 'forja capacidades', nivel: 'ok', detalhe: m.capacidades(ligadas.join(', ')) };
|
|
312
|
+
}
|
|
313
|
+
function checarForja(carregado, s = sondasPadraoDoDoctor(carregado.raiz)) {
|
|
314
|
+
const m = (0, locale_1.msg)().forja.doctor;
|
|
315
|
+
const declarada = carregado.manifesto.forja;
|
|
316
|
+
const dependeDaForja = carregado.manifesto.ci.required_for_ship || declarada !== undefined;
|
|
317
|
+
const linha = (nome, nivel, detalhe, correcao) => {
|
|
318
|
+
const n = nivel === 'fail' && !dependeDaForja ? 'warn' : nivel;
|
|
319
|
+
return { nome, nivel: n, detalhe, ...(n !== 'ok' && correcao ? { correcao } : {}) };
|
|
320
|
+
};
|
|
321
|
+
const url = s.urlDoRemoto(carregado.raiz, exports.REMOTO_DA_FORJA);
|
|
322
|
+
const endereco = url ? (0, endereco_1.lerEnderecoDoRemoto)(url) : null;
|
|
323
|
+
if (!endereco) {
|
|
324
|
+
return declarada ? [linha('forja identidade', 'warn', m.semHostComBloco(exports.REMOTO_DA_FORJA), m.semHostCorrecao(exports.REMOTO_DA_FORJA))] : [];
|
|
325
|
+
}
|
|
326
|
+
const resolvida = (0, resolver_1.resolverForja)({ endereco, manifesto: declarada, sondas: s.sondas, cache: s.cache, agoraMs: s.agoraMs() });
|
|
327
|
+
if (!resolvida.ok) {
|
|
328
|
+
return [linha('forja identidade', 'fail', (0, locale_1.msg)().forja.motivo(resolvida.erro, null), resolvida.erro.codigo === 'forja.remoto-divergente' ? m.divergenteCorrecao : m.identidadeCorrecao)];
|
|
329
|
+
}
|
|
330
|
+
const f = resolvida.valor;
|
|
331
|
+
// Remoto http sem porta declarada no manifesto: a web e a do remoto, sem TLS.
|
|
332
|
+
const http = endereco.protocolo === 'http' && declarada?.porta === undefined;
|
|
333
|
+
const portaWeb = f.porta ?? (http ? 80 : 443);
|
|
334
|
+
const checks = [linha('forja identidade', 'ok', identidade(f, portaWeb))];
|
|
335
|
+
if (!alcanceETls(f, portaWeb, http, s, linha, checks))
|
|
336
|
+
return checks;
|
|
337
|
+
if (!cliELogin(f, http, s, linha, checks))
|
|
338
|
+
return checks;
|
|
339
|
+
// O login ja foi conferido: as chamadas da API nao repetem o `auth status`.
|
|
340
|
+
const api = (0, api_1.chamadorDaApi)(f, { rodar: s.rodar, agoraMs: s.agoraMs, logins: new Map([[(0, api_1.chaveDoLogin)(f), true]]) });
|
|
341
|
+
if (!servidor(f, s, api, linha, checks))
|
|
342
|
+
return checks;
|
|
343
|
+
checks.push(escopo(f, api, linha, s.transporteDoShip?.(carregado.raiz) === 'forja-https'), projetoDaForja(f, api, linha), capacidades(f));
|
|
344
|
+
return checks;
|
|
345
|
+
}
|
|
@@ -46,7 +46,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
46
46
|
};
|
|
47
47
|
})();
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
-
exports.COMANDO_DE_INSTALAR_A_BATIDA = exports.ATRASO_DA_BATIDA_MIN = exports.COMANDO_DO_TEMPLATE = exports.SCRIPT_DA_VARREDURA = exports.BATIDA_DO_TEMPLATE = void 0;
|
|
49
|
+
exports.ARQUIVO_DO_TRANSPORTE = exports.COMANDO_DE_INSTALAR_A_BATIDA = exports.ATRASO_DA_BATIDA_MIN = exports.COMANDO_DO_TEMPLATE = exports.SCRIPT_DA_VARREDURA = exports.BATIDA_DO_TEMPLATE = void 0;
|
|
50
50
|
exports.lerCrontabDoSistema = lerCrontabDoSistema;
|
|
51
51
|
exports.intervaloEmMinutos = intervaloEmMinutos;
|
|
52
52
|
exports.valorNoShell = valorNoShell;
|
|
@@ -62,11 +62,16 @@ exports.citarNoShell = citarNoShell;
|
|
|
62
62
|
exports.scriptDaVarreduraDoOrk = scriptDaVarreduraDoOrk;
|
|
63
63
|
exports.comandoDaVarredura = comandoDaVarredura;
|
|
64
64
|
exports.checarCronDoPulse = checarCronDoPulse;
|
|
65
|
+
exports.batidaNoDoctor = batidaNoDoctor;
|
|
66
|
+
exports.ultimaEntrega = ultimaEntrega;
|
|
67
|
+
exports.checarTransporteDoPulse = checarTransporteDoPulse;
|
|
65
68
|
const fs = __importStar(require("node:fs"));
|
|
66
69
|
const os = __importStar(require("node:os"));
|
|
67
70
|
const path = __importStar(require("node:path"));
|
|
68
71
|
const util_1 = require("./util");
|
|
69
72
|
const locale_1 = require("./locale");
|
|
73
|
+
const horario_1 = require("./horario");
|
|
74
|
+
const maquina_1 = require("./maquina");
|
|
70
75
|
/** A batida do template `monitor/pulse.cron` (I-50): a menor cadencia das tags. */
|
|
71
76
|
exports.BATIDA_DO_TEMPLATE = '*/15 * * * *';
|
|
72
77
|
/** O script que o template agenda; a linha do crontab e achada por ele. */
|
|
@@ -341,9 +346,116 @@ function checarCronDoPulse(dirMonitor, raizDoCheckout, ler = lerCrontabDoSistema
|
|
|
341
346
|
lentas.push({ linha, comando: partes?.comando ?? comandoSugerido, intervalo });
|
|
342
347
|
}
|
|
343
348
|
if (lentas.length < linhas.length) {
|
|
349
|
+
// RM-063 (fatia 3, H1): a linha no crontab nao prova que a batida roda (cron parado, script que cai antes do log).
|
|
350
|
+
// Com thread aberta, a ultima rodada mais velha que o atraso reprova; sem rodada nenhuma ainda, ou com a batida
|
|
351
|
+
// instalada ha menos de 30 min depois da ultima rodada, a linha recem-instalada vale.
|
|
352
|
+
if (abertas > 0 && haMin !== null && haMin > exports.ATRASO_DA_BATIDA_MIN && !recemInstalada(raizDoCheckout, rodada?.em ?? null)) {
|
|
353
|
+
return { nome, nivel: 'fail', detalhe: (0, locale_1.msg)().doctor.batidaAtrasada(haMin, linhas.length), correcao: (0, locale_1.msg)().doctor.batidaAtrasadaCorrecao };
|
|
354
|
+
}
|
|
344
355
|
return { nome, nivel: 'ok', detalhe: (0, locale_1.msg)().doctor.cronOk(linhas.length) };
|
|
345
356
|
}
|
|
346
357
|
const l = lentas[0];
|
|
347
358
|
return { nome, nivel: 'warn', detalhe: (0, locale_1.msg)().doctor.cronLento((0, locale_1.msg)().doctor.cronRitmo(l.intervalo), l.linha),
|
|
348
359
|
correcao: (0, locale_1.msg)().doctor.cronTroque(linhaNova(l.comando)) };
|
|
349
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* A batida deste projeto foi instalada (`batida_instalada` no ledger da maquina) depois da ultima rodada e ha menos de
|
|
363
|
+
* 30 min: o `hitl.log` velho de antes da instalacao nao e atraso, a primeira rodada ainda vem.
|
|
364
|
+
*/
|
|
365
|
+
function recemInstalada(raizDoCheckout, ultimaRodadaEm, agora = Date.now()) {
|
|
366
|
+
let eventos = [];
|
|
367
|
+
try {
|
|
368
|
+
eventos = fs.readFileSync(path.join((0, maquina_1.pastaDoUsuario)(), 'ledger.jsonl'), 'utf8').split('\n').filter(Boolean)
|
|
369
|
+
.map((l) => { try {
|
|
370
|
+
return JSON.parse(l);
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
return {};
|
|
374
|
+
} });
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
const instalada = eventos.filter((e) => e.tipo === 'batida_instalada' && typeof e.projeto === 'string' &&
|
|
380
|
+
mesmoCaminho(e.projeto, raizDoCheckout) && typeof e.ts === 'string').map((e) => Date.parse(e.ts)).filter(Number.isFinite).at(-1);
|
|
381
|
+
if (instalada === undefined)
|
|
382
|
+
return false;
|
|
383
|
+
const rodada = ultimaRodadaEm ? Date.parse(ultimaRodadaEm) : Number.NEGATIVE_INFINITY;
|
|
384
|
+
return instalada > rodada && agora - instalada <= exports.ATRASO_DA_BATIDA_MIN * 60000;
|
|
385
|
+
}
|
|
386
|
+
function batidaNoDoctor(dirMonitor, raizDoCheckout, opcoes) {
|
|
387
|
+
const abertas = opcoes.abertas ?? threadsAbertasNoEstado(path.dirname(dirMonitor));
|
|
388
|
+
const rodada = ultimaRodadaDaVarredura(dirMonitor);
|
|
389
|
+
const agora = opcoes.agora ?? Date.now();
|
|
390
|
+
const haMin = rodada ? Math.max(0, Math.floor((agora - Date.parse(rodada.em)) / 60000)) : null;
|
|
391
|
+
const leitura = (opcoes.ler ?? lerCrontabDoSistema)();
|
|
392
|
+
const instalada = leitura.ok ? entradasDaVarredura(leitura.texto).some((e) => entradaDoProjeto(e, raizDoCheckout)) : null;
|
|
393
|
+
const atrasada = abertas > 0 && (haMin !== null ? haMin > exports.ATRASO_DA_BATIDA_MIN && !recemInstalada(raizDoCheckout, rodada?.em ?? null, agora)
|
|
394
|
+
: instalada !== true);
|
|
395
|
+
const quando = rodada ? (0, horario_1.formatarDataHoraRotulada)(rodada.em, { agora: new Date(agora).toISOString() }) : null;
|
|
396
|
+
const aviso = !atrasada ? null : haMin !== null
|
|
397
|
+
? `Orkastery: a fabrica ${opcoes.projeto} na maquina ${opcoes.maquina} esta sem batida ha ${haMin} min (ultima rodada em ${quando}` +
|
|
398
|
+
`${rodada?.code ? `, codigo ${rodada.code}` : ''}), com ${abertas} thread(s) aberta(s). Confira com: ork fabrica batida status`
|
|
399
|
+
: `Orkastery: a fabrica ${opcoes.projeto} na maquina ${opcoes.maquina} nao tem batida (nenhuma rodada da varredura e a linha nao ` +
|
|
400
|
+
`esta no crontab), com ${abertas} thread(s) aberta(s). Instale com: ork fabrica batida instalar`;
|
|
401
|
+
return { threadsAbertas: abertas, instalada, ultimaRodadaEm: rodada?.em ?? null, codigo: rodada?.code ?? null, haMin,
|
|
402
|
+
limiteMin: exports.ATRASO_DA_BATIDA_MIN, atrasada, aviso };
|
|
403
|
+
}
|
|
404
|
+
// ---------------------------------------------------------------------------
|
|
405
|
+
// RM-063 (fatia 3, H4): a falha do transporte do pulse, que a entrega grava em `transporte.log`.
|
|
406
|
+
// ---------------------------------------------------------------------------
|
|
407
|
+
exports.ARQUIVO_DO_TRANSPORTE = 'transporte.log';
|
|
408
|
+
/** A entrega mais velha que isto nao e mais noticia: o doctor nao acusa a falha de ontem. */
|
|
409
|
+
const VALIDADE_DA_FALHA_MS = 24 * 60 * 60 * 1000;
|
|
410
|
+
/** A ultima entrega registrada no `transporte.log` (lida do fim, com teto). */
|
|
411
|
+
function ultimaEntrega(dirMonitor) {
|
|
412
|
+
let texto;
|
|
413
|
+
try {
|
|
414
|
+
const fd = fs.openSync(path.join(dirMonitor, exports.ARQUIVO_DO_TRANSPORTE), 'r');
|
|
415
|
+
try {
|
|
416
|
+
const tamanho = fs.fstatSync(fd).size, lido = Math.min(tamanho, 64 * 1024);
|
|
417
|
+
const buffer = Buffer.alloc(lido);
|
|
418
|
+
fs.readSync(fd, buffer, 0, lido, tamanho - lido);
|
|
419
|
+
texto = buffer.toString('utf8');
|
|
420
|
+
}
|
|
421
|
+
finally {
|
|
422
|
+
fs.closeSync(fd);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
for (const linha of texto.split('\n').reverse()) {
|
|
429
|
+
try {
|
|
430
|
+
const e = JSON.parse(linha);
|
|
431
|
+
if (e.tipo !== 'transporte_entrega' || typeof e.ts !== 'string' || !Array.isArray(e.tentativas))
|
|
432
|
+
continue;
|
|
433
|
+
return { ts: e.ts, oQue: String(e.oQue ?? ''), ok: e.ok === true, host: typeof e.host === 'string' ? e.host : null, tentativas: e.tentativas };
|
|
434
|
+
}
|
|
435
|
+
catch { /* linha cortada */ }
|
|
436
|
+
}
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Check "transporte do pulse": a ultima entrega do resumo. Saiu pelo primeiro transporte, ok; saiu pelo outro host
|
|
441
|
+
* configurado, aviso; nao saiu por nenhum, falha. `null` sem `pulse-host.json`, ou sem entrega nas ultimas 24 h.
|
|
442
|
+
*/
|
|
443
|
+
function checarTransporteDoPulse(dirMonitor, agora = Date.now()) {
|
|
444
|
+
if (!fs.existsSync(path.join(dirMonitor, 'pulse-host.json')))
|
|
445
|
+
return null;
|
|
446
|
+
const e = ultimaEntrega(dirMonitor);
|
|
447
|
+
if (!e || !(agora - Date.parse(e.ts) <= VALIDADE_DA_FALHA_MS))
|
|
448
|
+
return null;
|
|
449
|
+
const nome = 'transporte do pulse';
|
|
450
|
+
const quando = (0, horario_1.formatarDataHoraRotulada)(e.ts, { agora: new Date(agora).toISOString() });
|
|
451
|
+
if (!e.ok) {
|
|
452
|
+
const tentativas = e.tentativas.map((t) => `${t.host}: ${t.codigo ?? 'sem código'}`).join('; ');
|
|
453
|
+
return { nome, nivel: 'fail', detalhe: (0, locale_1.msg)().doctor.transporteFalhou(quando, tentativas), correcao: (0, locale_1.msg)().doctor.transporteCorrecao };
|
|
454
|
+
}
|
|
455
|
+
const falhas = e.tentativas.filter((t) => !t.ok);
|
|
456
|
+
if (falhas.length) {
|
|
457
|
+
return { nome, nivel: 'warn', detalhe: (0, locale_1.msg)().doctor.transporteDesvio(falhas.map((t) => t.host).join(', '), e.host ?? '?', quando),
|
|
458
|
+
correcao: (0, locale_1.msg)().doctor.transporteCorrecao };
|
|
459
|
+
}
|
|
460
|
+
return { nome, nivel: 'ok', detalhe: (0, locale_1.msg)().doctor.transporteOk(e.host ?? '?', quando) };
|
|
461
|
+
}
|