@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
package/dist/hitl-contract.js
CHANGED
|
@@ -29,6 +29,7 @@ exports.motivoDoPedido = motivoDoPedido;
|
|
|
29
29
|
/** D1: contrato de pedido, independente do host. Expiração nunca autoriza. */
|
|
30
30
|
const modos_1 = require("./modos");
|
|
31
31
|
const types_1 = require("./types");
|
|
32
|
+
const locale_1 = require("./locale");
|
|
32
33
|
exports.CONTRATO_HITL = 'ork.hitl/v1';
|
|
33
34
|
/**
|
|
34
35
|
* D5: a lista FECHADA de atos que nao se desfazem. Ela mora no nucleo, congelada, e nao no
|
|
@@ -216,7 +217,7 @@ function validarComumV2(v) {
|
|
|
216
217
|
if (!identificador(v.id) || !identificador(v.thread) || !types_1.FASES.includes(v.fase) ||
|
|
217
218
|
!modos_1.MODOS_LEGADOS.includes(v.modo) || !iso(v.criadoEm) ||
|
|
218
219
|
!['resumo', 'detalhada', 'profunda'].includes(v.profundidade)) {
|
|
219
|
-
throw new
|
|
220
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoComumInvalido);
|
|
220
221
|
}
|
|
221
222
|
}
|
|
222
223
|
/**
|
|
@@ -225,14 +226,15 @@ function validarComumV2(v) {
|
|
|
225
226
|
* mandou os tres campos nao tinha como saber que o problema era o tamanho.
|
|
226
227
|
*/
|
|
227
228
|
function problemaDaLinha(campo, v, teto) {
|
|
229
|
+
const m = (0, locale_1.msg)().decisao;
|
|
228
230
|
if (typeof v !== 'string' || !v.trim())
|
|
229
|
-
return { ausente: true, texto:
|
|
231
|
+
return { ausente: true, texto: m.linhaFalta(campo) };
|
|
230
232
|
if (/[\r\n]/.test(v))
|
|
231
|
-
return { ausente: false, texto:
|
|
233
|
+
return { ausente: false, texto: m.linhaQuebrada(campo) };
|
|
232
234
|
if (/[\x00-\x08\x0b-\x1f\x7f]/.test(v))
|
|
233
|
-
return { ausente: false, texto:
|
|
235
|
+
return { ausente: false, texto: m.linhaControle(campo) };
|
|
234
236
|
if (v.length > teto)
|
|
235
|
-
return { ausente: false, texto:
|
|
237
|
+
return { ausente: false, texto: m.linhaLonga(campo, v.length, teto) };
|
|
236
238
|
return null;
|
|
237
239
|
}
|
|
238
240
|
/**
|
|
@@ -249,121 +251,121 @@ exports.CAMPOS_DA_DECISAO_NO_MCP = Object.freeze({
|
|
|
249
251
|
});
|
|
250
252
|
/** Troca o nome interno do campo, onde a recusa o cita, pelo nome da superficie. */
|
|
251
253
|
function recusaNaSuperficie(mensagem, nomes) {
|
|
252
|
-
return mensagem.replace(/(falta |: )(decidido|porque|comoMudar|custoDeReverter\.agora|custoDeReverter\.depois|criterio\.referencia)(?=\)| tem )/g, (_, antes, campo) => `${antes}${nomes[campo] ?? campo}`);
|
|
254
|
+
return mensagem.replace(/(falta |missing |: )(decidido|porque|comoMudar|custoDeReverter\.agora|custoDeReverter\.depois|criterio\.referencia)(?=\)| tem | has )/g, (_, antes, campo) => `${antes}${nomes[campo] ?? campo}`);
|
|
253
255
|
}
|
|
254
256
|
function validarDecidido(v) {
|
|
255
257
|
for (const campo of exports.CAMPOS_DE_GATE) {
|
|
256
258
|
if (v[campo] !== undefined)
|
|
257
|
-
throw new
|
|
259
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCampoDeGate(campo));
|
|
258
260
|
}
|
|
259
261
|
for (const campo of ['decidido', 'porque', 'comoMudar']) {
|
|
260
262
|
const problema = problemaDaLinha(campo, v[campo], exports.TETOS_HITL_V2.campoDaDecisao);
|
|
261
263
|
if (problema?.ausente)
|
|
262
|
-
throw new
|
|
264
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCamposObrigatorios(problema.texto));
|
|
263
265
|
if (problema)
|
|
264
|
-
throw new
|
|
266
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCampoInvalido(problema.texto));
|
|
265
267
|
}
|
|
266
268
|
const custo = v.custoDeReverter;
|
|
267
269
|
const problemasDoCusto = ['agora', 'depois']
|
|
268
270
|
.map(lado => problemaDaLinha(`custoDeReverter.${lado}`, objeto(custo) ? custo[lado] : undefined, exports.TETOS_HITL_V2.custo));
|
|
269
271
|
if (problemasDoCusto.some(p => p?.ausente)) {
|
|
270
|
-
throw new
|
|
272
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCustoObrigatorio);
|
|
271
273
|
}
|
|
272
274
|
const doCusto = problemasDoCusto.find(p => p !== null);
|
|
273
275
|
if (doCusto)
|
|
274
|
-
throw new
|
|
276
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCustoInvalido(doCusto.texto));
|
|
275
277
|
const criterio = v.criterio;
|
|
276
278
|
const daReferencia = objeto(criterio) ? problemaDaLinha('criterio.referencia', criterio.referencia, 300) : null;
|
|
277
279
|
if (!objeto(criterio) || !['manifesto', 'ledger', 'medicao'].includes(criterio.tipo) || daReferencia?.ausente) {
|
|
278
|
-
throw new
|
|
280
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCriterioObrigatorio);
|
|
279
281
|
}
|
|
280
282
|
if (daReferencia)
|
|
281
|
-
throw new
|
|
283
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCriterioInvalido(daReferencia.texto));
|
|
282
284
|
// R1, porta fechada: ato irreversivel nunca se qualifica como decisao informada.
|
|
283
285
|
if (v.irreversivel === true)
|
|
284
|
-
throw new
|
|
286
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoIrreversivel);
|
|
285
287
|
}
|
|
286
288
|
function validarAlternativas(v) {
|
|
287
289
|
const alternativas = v.alternativas;
|
|
288
290
|
if (!Array.isArray(alternativas) || alternativas.length < 2 || alternativas.length > exports.LETRAS_DE_ALTERNATIVA.length) {
|
|
289
|
-
throw new
|
|
291
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativas);
|
|
290
292
|
}
|
|
291
293
|
let recomendadas = 0;
|
|
292
294
|
alternativas.forEach((bruta, i) => {
|
|
293
295
|
if (!objeto(bruta) || bruta.letra !== exports.LETRAS_DE_ALTERNATIVA[i]) {
|
|
294
|
-
throw new
|
|
296
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativas);
|
|
295
297
|
}
|
|
296
298
|
if (!linhaUnica(bruta.texto, exports.TETOS_HITL_V2.alternativaTexto))
|
|
297
|
-
throw new
|
|
299
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativaSemTexto);
|
|
298
300
|
if (!['aprovar', 'recusar', 'responder', 'esperar'].includes(bruta.acao)) {
|
|
299
|
-
throw new
|
|
301
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativaSemAcao);
|
|
300
302
|
}
|
|
301
303
|
if (!linhaUnica(bruta.consequencia, exports.TETOS_HITL_V2.consequencia)) {
|
|
302
|
-
throw new
|
|
304
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlternativaSemConsequencia);
|
|
303
305
|
}
|
|
304
306
|
if (bruta.recomendada === undefined) {
|
|
305
307
|
if (bruta.porque !== undefined)
|
|
306
|
-
throw new
|
|
308
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoPorqueSoRecomendada);
|
|
307
309
|
return;
|
|
308
310
|
}
|
|
309
311
|
if (bruta.recomendada !== true)
|
|
310
|
-
throw new
|
|
312
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoRecomendadaBoolean);
|
|
311
313
|
if (!linhaUnica(bruta.porque, exports.TETOS_HITL_V2.porque)) {
|
|
312
|
-
throw new
|
|
314
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoRecomendadaSemPorque);
|
|
313
315
|
}
|
|
314
316
|
recomendadas++;
|
|
315
317
|
});
|
|
316
318
|
if (recomendadas !== 1)
|
|
317
|
-
throw new
|
|
319
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoUmaRecomendada);
|
|
318
320
|
}
|
|
319
321
|
function validarPergunta(v) {
|
|
320
322
|
if (!linhaUnica(v.pergunta, exports.TETOS_HITL_V2.pergunta)) {
|
|
321
|
-
throw new
|
|
323
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoPerguntaFrase);
|
|
322
324
|
}
|
|
323
325
|
if (!texto(v.motivo, 100))
|
|
324
|
-
throw new
|
|
326
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoMotivoInvalido);
|
|
325
327
|
validarAlternativas(v);
|
|
326
328
|
if (!Array.isArray(v.corpo) || v.corpo.length > exports.TETOS_HITL_V2.corpoLinhas ||
|
|
327
329
|
v.corpo.some(l => !linhaUnica(l, exports.TETOS_HITL_V2.corpoLinha))) {
|
|
328
|
-
throw new
|
|
330
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCorpoLinhas);
|
|
329
331
|
}
|
|
330
332
|
if (!['objetiva', 'aberta'].includes(v.tipoDeResposta))
|
|
331
|
-
throw new
|
|
333
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoTipoRespostaInvalido);
|
|
332
334
|
if (!/^[0-9A-Za-z]{3,8}$/.test(String(v.codigo ?? '')))
|
|
333
|
-
throw new
|
|
335
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoCodigoInvalido);
|
|
334
336
|
const alvo = v.alvo;
|
|
335
337
|
if (!objeto(alvo) || !(alvo.tipo === 'gate' && texto(alvo.sobre, 100) ||
|
|
336
338
|
alvo.tipo === 'session' && identificador(alvo.sessionId) && ['claude-bg', 'codex'].includes(alvo.runtime))) {
|
|
337
|
-
throw new
|
|
339
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAlvoInvalido);
|
|
338
340
|
}
|
|
339
341
|
const aceita = v.respostaAceita;
|
|
340
342
|
if (!objeto(aceita) || !['opcao', 'texto'].includes(aceita.tipo) ||
|
|
341
343
|
!Number.isInteger(aceita.maxCaracteres) || Number(aceita.maxCaracteres) < 1 || Number(aceita.maxCaracteres) > 4096) {
|
|
342
|
-
throw new
|
|
344
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoRespostaInvalida);
|
|
343
345
|
}
|
|
344
346
|
if (!iso(v.prazo) || Date.parse(v.prazo) <= Date.parse(v.criadoEm) ||
|
|
345
347
|
!['esperar', 'escalar', 'seguir-recomendada'].includes(v.acaoPadraoAoExpirar)) {
|
|
346
|
-
throw new
|
|
348
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoPrazoInvalido);
|
|
347
349
|
}
|
|
348
350
|
if (v.dependenciaTecnica !== undefined) {
|
|
349
351
|
const d = v.dependenciaTecnica;
|
|
350
352
|
if (!objeto(d) || !linhaUnica(d.comando, exports.TETOS_HITL_V2.campoDaDecisao) || !linhaUnica(d.porque, exports.TETOS_HITL_V2.porque)) {
|
|
351
|
-
throw new
|
|
353
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoDependenciaInvalida);
|
|
352
354
|
}
|
|
353
355
|
}
|
|
354
356
|
if (typeof v.irreversivel !== 'boolean')
|
|
355
|
-
throw new
|
|
357
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoIrreversivelAusente);
|
|
356
358
|
if (v.irreversivel) {
|
|
357
359
|
if (!exports.ATOS_IRREVERSIVEIS.includes(String(v.ato))) {
|
|
358
|
-
throw new
|
|
360
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAtoIrreversivelInvalido);
|
|
359
361
|
}
|
|
360
362
|
// D5, primeira das quatro barreiras: a combinacao nao chega a existir.
|
|
361
363
|
if (v.acaoPadraoAoExpirar === 'seguir-recomendada') {
|
|
362
|
-
throw new
|
|
364
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoIrreversivelExpira);
|
|
363
365
|
}
|
|
364
366
|
}
|
|
365
367
|
else if (v.ato !== undefined) {
|
|
366
|
-
throw new
|
|
368
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoAtoSoIrreversivel);
|
|
367
369
|
}
|
|
368
370
|
}
|
|
369
371
|
// ---------------------------------------------------------------------------
|
|
@@ -396,33 +398,33 @@ exports.SelecaoRecusada = SelecaoRecusada;
|
|
|
396
398
|
*/
|
|
397
399
|
function exigirSelecaoDeConducao(pedido) {
|
|
398
400
|
if (!ehV2(pedido)) {
|
|
399
|
-
throw new SelecaoRecusada('hitl.selecao.versao',
|
|
401
|
+
throw new SelecaoRecusada('hitl.selecao.versao', (0, locale_1.msg)().decisao.selecaoVersao);
|
|
400
402
|
}
|
|
401
403
|
if (pedido.classe === 'decidido')
|
|
402
404
|
return;
|
|
403
405
|
const n = pedido.alternativas.length;
|
|
404
406
|
if (n < exports.MINIMO_DE_ALTERNATIVAS_DE_CONDUCAO || n > exports.MAXIMO_DE_ALTERNATIVAS_DE_CONDUCAO) {
|
|
405
|
-
throw new SelecaoRecusada('hitl.selecao.fora-da-faixa',
|
|
407
|
+
throw new SelecaoRecusada('hitl.selecao.fora-da-faixa', (0, locale_1.msg)().decisao.selecaoFaixa(exports.MINIMO_DE_ALTERNATIVAS_DE_CONDUCAO, exports.MAXIMO_DE_ALTERNATIVAS_DE_CONDUCAO, n));
|
|
406
408
|
}
|
|
407
409
|
const recomendadas = pedido.alternativas.filter(a => a.recomendada).length;
|
|
408
410
|
if (recomendadas !== 1) {
|
|
409
|
-
throw new SelecaoRecusada('hitl.selecao.recomendada',
|
|
411
|
+
throw new SelecaoRecusada('hitl.selecao.recomendada', (0, locale_1.msg)().decisao.selecaoRecomendada(recomendadas));
|
|
410
412
|
}
|
|
411
413
|
const pedeTexto = pedido.tipoDeResposta === 'aberta' || pedido.respostaAceita.tipo === 'texto';
|
|
412
414
|
if (pedeTexto && !pedido.dependenciaTecnica) {
|
|
413
|
-
throw new SelecaoRecusada('hitl.selecao.texto-livre',
|
|
415
|
+
throw new SelecaoRecusada('hitl.selecao.texto-livre', (0, locale_1.msg)().decisao.selecaoTextoLivre);
|
|
414
416
|
}
|
|
415
417
|
}
|
|
416
418
|
/** Valida `ork.hitl/v2`. Nunca aceita um v1: quem julga v1 e o validador congelado. */
|
|
417
419
|
function validarPedidoHitlV2(v) {
|
|
418
420
|
if (!objeto(v) || v.contrato !== exports.CONTRATO_HITL_V2)
|
|
419
|
-
throw new
|
|
421
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoDesconhecido);
|
|
420
422
|
validarComumV2(v);
|
|
421
423
|
if (v.classe === 'decidido')
|
|
422
424
|
return validarDecidido(v);
|
|
423
425
|
if (v.classe === 'pergunta')
|
|
424
426
|
return validarPergunta(v);
|
|
425
|
-
throw new
|
|
427
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.contratoClasseInvalida);
|
|
426
428
|
}
|
|
427
429
|
/**
|
|
428
430
|
* O leitor das duas versoes. Despacha por contrato: v1 pelo validador congelado, v2 pelo novo.
|
|
@@ -473,7 +475,8 @@ function classificarDecisao(sinais) {
|
|
|
473
475
|
* `hitl.formato` para tudo tornaria o motivo tao generico quanto a string que ele substitui.
|
|
474
476
|
*/
|
|
475
477
|
function motivoDaRecusaDeFormato(erro) {
|
|
476
|
-
|
|
478
|
+
// RM-061 F3c: a recusa do catalogo e classificada pelo texto pt-BR, a fonte, em qualquer lingua de quem a leu.
|
|
479
|
+
const mensagem = erro instanceof locale_1.ErroDoCatalogo ? erro.montar((0, locale_1.msg)('pt-BR')) : erro instanceof Error ? erro.message : String(erro);
|
|
477
480
|
return mensagem.startsWith('pedido HITL v2: ') && !mensagem.includes('contrato inválido')
|
|
478
481
|
? 'hitl.formato' : null;
|
|
479
482
|
}
|
package/dist/hitl-curto.js
CHANGED
|
@@ -36,6 +36,7 @@ exports.desdeDoPedido = desdeDoPedido;
|
|
|
36
36
|
const hitl_1 = require("./hitl");
|
|
37
37
|
const hitl_contract_1 = require("./hitl-contract");
|
|
38
38
|
const horario_1 = require("./horario");
|
|
39
|
+
const locale_1 = require("./locale");
|
|
39
40
|
exports.CONTRATO_PEDIDO_CURTO = 'ork.hitl-curto/v1';
|
|
40
41
|
/** RM-057: o selo que o dono procura na lista, igual em todo canal. */
|
|
41
42
|
exports.SELO_DA_RECOMENDADA = 'Recomendação';
|
|
@@ -60,7 +61,7 @@ const linha = (texto, teto = TETO_DA_LINHA) => {
|
|
|
60
61
|
function entradaDoPedido(pedido, desde) {
|
|
61
62
|
(0, hitl_contract_1.validarPedidoHitl)(pedido);
|
|
62
63
|
if (!(0, hitl_contract_1.ehV2)(pedido) || pedido.classe !== 'pergunta') {
|
|
63
|
-
throw new Error(
|
|
64
|
+
throw new Error((0, locale_1.msg)().decisao.curto.soPergunta);
|
|
64
65
|
}
|
|
65
66
|
const alvo = (0, hitl_contract_1.alvoDoPedido)(pedido);
|
|
66
67
|
return {
|
|
@@ -74,32 +75,34 @@ function entradaDoPedido(pedido, desde) {
|
|
|
74
75
|
}
|
|
75
76
|
/** O que acontece sem resposta, em meia linha. Expirar nunca autoriza. */
|
|
76
77
|
function semResposta(e, agora) {
|
|
77
|
-
const
|
|
78
|
+
const m = (0, locale_1.msg)().decisao.curto;
|
|
79
|
+
const ate = e.prazo ? m.ate((0, horario_1.formatarHora)(e.prazo, { agora })) : '';
|
|
78
80
|
if (e.expiracao === 'seguir-recomendada')
|
|
79
|
-
return
|
|
81
|
+
return m.semRespostaRecomendada(ate);
|
|
80
82
|
if (e.expiracao === 'escalar')
|
|
81
|
-
return
|
|
82
|
-
return e.alvo?.tipo === 'session' ?
|
|
83
|
+
return m.semRespostaEscala(ate);
|
|
84
|
+
return e.alvo?.tipo === 'session' ? m.semRespostaSessao : m.semRespostaGate;
|
|
83
85
|
}
|
|
84
86
|
/**
|
|
85
87
|
* Monta o pedido curto. Recusa, em vez de cortar em silencio, o que o contrato nao aceita: menos
|
|
86
88
|
* de duas alternativas, mais de cinco, ou recomendada diferente de exatamente uma.
|
|
87
89
|
*/
|
|
88
90
|
function montarPedidoCurto(e, opcoes) {
|
|
91
|
+
const m = (0, locale_1.msg)().decisao.curto;
|
|
89
92
|
if (e.alternativas.length < 2 || e.alternativas.length > 5)
|
|
90
|
-
throw new Error(
|
|
93
|
+
throw new Error(m.alternativas);
|
|
91
94
|
if (e.alternativas.filter(a => a.recomendada).length !== 1)
|
|
92
|
-
throw new Error(
|
|
95
|
+
throw new Error(m.umaRecomendada);
|
|
93
96
|
const onde = e.alvo?.tipo === 'session'
|
|
94
|
-
?
|
|
95
|
-
:
|
|
96
|
-
const desde = e.desde ?
|
|
97
|
+
? m.sessaoParada(e.alvo.sessionId.slice(0, 8))
|
|
98
|
+
: m.faseParada(e.fase);
|
|
99
|
+
const desde = e.desde ? m.desde((0, horario_1.formatarDesde)(e.desde, { agora: opcoes.quando })) : '';
|
|
97
100
|
return {
|
|
98
101
|
contrato: exports.CONTRATO_PEDIDO_CURTO,
|
|
99
|
-
titulo: linha([e.thread, e.fase].filter(Boolean).join(' · ') ||
|
|
102
|
+
titulo: linha(e.titulo ?? ([e.thread, e.fase].filter(Boolean).join(' · ') || m.semThread)),
|
|
100
103
|
pergunta: linha(e.pergunta),
|
|
101
|
-
trava: linha(`${onde}${desde}. ${semResposta(e, opcoes.quando)}`),
|
|
102
|
-
...(e.ato ? { semVolta:
|
|
104
|
+
trava: linha(e.trava ?? `${onde}${desde}. ${semResposta(e, opcoes.quando)}`),
|
|
105
|
+
...(e.ato ? { semVolta: m.semVolta(m.atos[e.ato]) } : {}),
|
|
103
106
|
corpo: (e.corpo ?? []).slice(0, exports.TETO_DE_LINHAS_DO_CORPO).map(l => linha(l)).filter(Boolean),
|
|
104
107
|
alternativas: e.alternativas.map(a => ({ chave: a.chave, texto: linha(a.texto, 140), consequencia: linha(a.consequencia, 140),
|
|
105
108
|
...(a.recomendada ? { recomendada: { porque: linha(a.recomendada.porque, 140) } } : {}) })),
|
|
@@ -109,43 +112,52 @@ function montarPedidoCurto(e, opcoes) {
|
|
|
109
112
|
/** A ultima linha: exatamente o que digitar, sem identificador longo. */
|
|
110
113
|
function linhaDeResposta(p, canal) {
|
|
111
114
|
const r = p.responder, recomendada = p.alternativas.find(a => a.recomendada).chave;
|
|
115
|
+
const m = (0, locale_1.msg)().decisao.curto;
|
|
112
116
|
if (r.tipo === 'numero')
|
|
113
117
|
return null;
|
|
114
118
|
if (r.tipo === 'texto')
|
|
115
|
-
return `${canal === 'telegram' ? '↩️ ' : ''}
|
|
119
|
+
return `${canal === 'telegram' ? '↩️ ' : ''}${m.respostaTexto}`;
|
|
116
120
|
if (r.tipo === 'terminal')
|
|
117
|
-
return `${canal === 'telegram' ? '↩️ ' :
|
|
121
|
+
return `${canal === 'telegram' ? '↩️ ' : `${m.responder}: `}${m.respostaTerminal(recomendada, r.comando)}`;
|
|
118
122
|
if (r.tipo === 'dialogo')
|
|
119
|
-
return `${canal === 'telegram' ? '↩️ ' : ''}
|
|
123
|
+
return `${canal === 'telegram' ? '↩️ ' : ''}${m.respostaDialogo}`;
|
|
124
|
+
if (r.tipo === 'letras') {
|
|
125
|
+
// RM-057: as letras reais da pergunta, nunca uma linha para copiar; o detalhe fica a um pedido de distancia.
|
|
126
|
+
const letras = m.listaDeLetras(p.alternativas.map(a => a.chave));
|
|
127
|
+
return canal === 'telegram' ? `↩️ ${m.respostaLetras(letras, r.codigo)}` : `${m.responder}: ${m.respostaLetrasHost(letras, r.codigo)}`;
|
|
128
|
+
}
|
|
120
129
|
return canal === 'telegram'
|
|
121
|
-
?
|
|
122
|
-
:
|
|
130
|
+
? m.respostaTelegram(r.codigo, recomendada)
|
|
131
|
+
: m.respostaHost(r.codigo, recomendada);
|
|
123
132
|
}
|
|
124
133
|
/**
|
|
125
134
|
* O texto do pedido no canal. Telegram e terminal dizem a mesma coisa com marcadores diferentes;
|
|
126
135
|
* nenhum dos dois passa de `TETO_DE_LINHAS_DO_PEDIDO` linhas.
|
|
127
136
|
*/
|
|
128
137
|
function textoDoPedidoCurto(p, canal) {
|
|
138
|
+
const m = (0, locale_1.msg)().decisao.curto;
|
|
129
139
|
if (p.contrato !== exports.CONTRATO_PEDIDO_CURTO)
|
|
130
|
-
throw new Error(
|
|
140
|
+
throw new Error(m.contratoInvalido);
|
|
131
141
|
const tg = canal === 'telegram';
|
|
132
142
|
const numero = p.responder.tipo === 'numero' ? `${p.responder.numero}. ` : '';
|
|
143
|
+
// RM-057 (resposta curta): a pergunta servida sozinha leva o numero do lote, para "1a" tambem valer.
|
|
144
|
+
const servida = p.responder.tipo === 'letras' && p.responder.numero ? `${p.responder.numero}. ` : '';
|
|
133
145
|
const linhas = [
|
|
134
|
-
`${tg && !numero ? '🔔 ' : ''}${numero}${tg || numero ? '' : 'Orkastery · '}${p.titulo}`,
|
|
135
|
-
`${tg ? '❓ ' :
|
|
136
|
-
`${tg ? '⏳ ' :
|
|
146
|
+
`${tg && !numero ? '🔔 ' : ''}${numero || servida}${tg || numero ? '' : 'Orkastery · '}${p.titulo}`,
|
|
147
|
+
`${tg ? '❓ ' : `${m.pergunta}: `}${p.pergunta}`,
|
|
148
|
+
`${tg ? '⏳ ' : `${m.situacao}: `}${p.trava}`,
|
|
137
149
|
...(p.semVolta ? [`${tg ? '🔒 ' : '! '}${p.semVolta}`] : []),
|
|
138
150
|
...p.corpo.map(l => `${tg ? '• ' : '- '}${l}`),
|
|
139
151
|
...p.alternativas.flatMap(a => [
|
|
140
|
-
`${a.chave}) ${a.texto}${a.recomendada ? (tg ? ` ✅ ${
|
|
141
|
-
...(a.recomendada ? [`
|
|
152
|
+
`${a.chave}) ${a.texto}${a.recomendada ? (tg ? ` ✅ ${m.selo}` : ` [${m.selo}]`) : ''}: ${a.consequencia}`,
|
|
153
|
+
...(a.recomendada ? [` ${m.porque}: ${a.recomendada.porque}`] : []),
|
|
142
154
|
]),
|
|
143
155
|
];
|
|
144
156
|
const resposta = linhaDeResposta(p, canal);
|
|
145
157
|
if (resposta)
|
|
146
158
|
linhas.push(resposta);
|
|
147
159
|
if (linhas.length > exports.TETO_DE_LINHAS_DO_PEDIDO)
|
|
148
|
-
throw new Error(
|
|
160
|
+
throw new Error(m.acimaDoTeto);
|
|
149
161
|
return linhas.join('\n');
|
|
150
162
|
}
|
|
151
163
|
/**
|
package/dist/hitl-gates.js
CHANGED
|
@@ -78,6 +78,7 @@ const memoria_humana_1 = require("./memoria-humana");
|
|
|
78
78
|
const hitl_canais_1 = require("./hitl-canais");
|
|
79
79
|
const hitl_native_1 = require("./hitl-native");
|
|
80
80
|
const modos_1 = require("./modos");
|
|
81
|
+
const locale_1 = require("./locale");
|
|
81
82
|
/**
|
|
82
83
|
* D12: o canal entra no corpo assinado, e é isso que o torna recibo em vez de rótulo.
|
|
83
84
|
* Hermes e OpenClaw compartilham transporte, mas usam chaves próprias e identidades
|
|
@@ -170,8 +171,9 @@ function autenticarResposta(thread, pedido, r, quando = new Date().toISOString()
|
|
|
170
171
|
*/
|
|
171
172
|
function resolverCriterio(raiz, pedido) {
|
|
172
173
|
const { tipo, referencia } = pedido.criterio;
|
|
174
|
+
const m = (0, locale_1.msg)().decisao;
|
|
173
175
|
if (tipo === 'medicao') {
|
|
174
|
-
return { resolve: true, detalhe:
|
|
176
|
+
return { resolve: true, detalhe: m.criterioMedicao };
|
|
175
177
|
}
|
|
176
178
|
if (tipo === 'manifesto') {
|
|
177
179
|
let alvo;
|
|
@@ -179,19 +181,19 @@ function resolverCriterio(raiz, pedido) {
|
|
|
179
181
|
alvo = (0, manifest_1.exigirManifesto)(raiz).manifesto;
|
|
180
182
|
}
|
|
181
183
|
catch {
|
|
182
|
-
return { resolve: false, detalhe:
|
|
184
|
+
return { resolve: false, detalhe: m.criterioManifestoIlegivel };
|
|
183
185
|
}
|
|
184
186
|
for (const parte of referencia.split('.')) {
|
|
185
187
|
if (!alvo || typeof alvo !== 'object' || !(parte in alvo)) {
|
|
186
|
-
return { resolve: false, detalhe:
|
|
188
|
+
return { resolve: false, detalhe: m.criterioManifestoSemChave(referencia) };
|
|
187
189
|
}
|
|
188
190
|
alvo = alvo[parte];
|
|
189
191
|
}
|
|
190
192
|
const vazio = alvo === undefined || alvo === null || alvo === '' ||
|
|
191
193
|
(Array.isArray(alvo) && alvo.length === 0);
|
|
192
194
|
return vazio
|
|
193
|
-
? { resolve: false, detalhe:
|
|
194
|
-
: { resolve: true, detalhe:
|
|
195
|
+
? { resolve: false, detalhe: m.criterioManifestoVazio(referencia) }
|
|
196
|
+
: { resolve: true, detalhe: m.criterioManifestoLido(referencia) };
|
|
195
197
|
}
|
|
196
198
|
// `ledger`: `<thread>#evento:<n>` (1-based) ou o `eventId` do proprio evento.
|
|
197
199
|
const comIndice = /^([a-zA-Z0-9][a-zA-Z0-9._-]{0,79})#evento:(\d+)$/.exec(referencia);
|
|
@@ -201,17 +203,17 @@ function resolverCriterio(raiz, pedido) {
|
|
|
201
203
|
eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, thread));
|
|
202
204
|
}
|
|
203
205
|
catch {
|
|
204
|
-
return { resolve: false, detalhe:
|
|
206
|
+
return { resolve: false, detalhe: m.criterioLedgerIlegivel(thread) };
|
|
205
207
|
}
|
|
206
208
|
if (comIndice) {
|
|
207
209
|
const n = Number(comIndice[2]);
|
|
208
210
|
return n >= 1 && n <= eventos.length
|
|
209
|
-
? { resolve: true, detalhe:
|
|
210
|
-
: { resolve: false, detalhe:
|
|
211
|
+
? { resolve: true, detalhe: m.criterioEvento(n, thread) }
|
|
212
|
+
: { resolve: false, detalhe: m.criterioEventoAusente(n, thread) };
|
|
211
213
|
}
|
|
212
214
|
return eventos.some(e => e.eventId === referencia)
|
|
213
|
-
? { resolve: true, detalhe:
|
|
214
|
-
: { resolve: false, detalhe:
|
|
215
|
+
? { resolve: true, detalhe: m.criterioEvento(referencia, thread) }
|
|
216
|
+
: { resolve: false, detalhe: m.criterioEventoAusente(referencia, thread) };
|
|
215
217
|
}
|
|
216
218
|
function registrarPedidoHitl(raiz, pedido) {
|
|
217
219
|
(0, hitl_contract_1.validarPedidoHitl)(pedido);
|
|
@@ -224,7 +226,7 @@ function registrarPedidoHitl(raiz, pedido) {
|
|
|
224
226
|
if ((0, hitl_contract_1.ehV2)(pedido) && pedido.classe === 'decidido') {
|
|
225
227
|
const { resolve, detalhe } = resolverCriterio(raiz, pedido);
|
|
226
228
|
if (!resolve)
|
|
227
|
-
throw new
|
|
229
|
+
throw new locale_1.ErroDoCatalogo((m) => m.decisao.criterioNaoResolve(detalhe));
|
|
228
230
|
}
|
|
229
231
|
return comLockHitl(raiz, pedido.thread, () => {
|
|
230
232
|
const t = (0, thread_1.lerThread)(raiz, pedido.thread), dir = (0, thread_1.dirThread)(raiz, t.id);
|
|
@@ -33,8 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.IDENTIDADE_DA_NOTA_NATIVA = exports.CONTRATO_RECIBO_DA_NOTA = void 0;
|
|
36
37
|
exports.chaveLocal = chaveLocal;
|
|
37
38
|
exports.gravarEvidenciaLocal = gravarEvidenciaLocal;
|
|
39
|
+
exports.gravarEvidenciaLocalNota = gravarEvidenciaLocalNota;
|
|
40
|
+
exports.conferirReciboLocalNota = conferirReciboLocalNota;
|
|
38
41
|
exports.gravarEvidenciaLocalSessao = gravarEvidenciaLocalSessao;
|
|
39
42
|
exports.validarEvidenciaLocalSessao = validarEvidenciaLocalSessao;
|
|
40
43
|
exports.validarEvidenciaLocal = validarEvidenciaLocal;
|
|
@@ -47,6 +50,16 @@ const thread_1 = require("./thread");
|
|
|
47
50
|
const ledger_1 = require("./ledger");
|
|
48
51
|
const hitl_contract_1 = require("./hitl-contract");
|
|
49
52
|
const hitl_local_atestado_1 = require("./hitl-local-atestado");
|
|
53
|
+
/**
|
|
54
|
+
* RM-059 (T8.1, D3 e D12 da thread ork-rm059ritual): o recibo da nota do MASTER pelo dialogo nativo. Mesmo cofre e mesma
|
|
55
|
+
* chave do gate; guarda o hash do porque, nunca o texto (o texto vai ao MASTER log da thread).
|
|
56
|
+
*/
|
|
57
|
+
exports.CONTRATO_RECIBO_DA_NOTA = 'ork.hitl-local-master-note/v1';
|
|
58
|
+
/**
|
|
59
|
+
* RM-059 (D12 da thread ork-rm059ritual): o `avaliadoPor` da nota pelo dialogo nativo. O host da conexao fica no
|
|
60
|
+
* `canal` e no recibo; a identidade e uma so, aceita pelo `autoriaHumana` de qualquer versao do `ork`.
|
|
61
|
+
*/
|
|
62
|
+
exports.IDENTIDADE_DA_NOTA_NATIVA = 'dono (dialogo nativo)';
|
|
50
63
|
const sha = (v) => (0, node_crypto_1.createHash)('sha256').update(v).digest('hex');
|
|
51
64
|
const uid = () => {
|
|
52
65
|
const atual = process.getuid?.();
|
|
@@ -222,6 +235,44 @@ function gravarEvidenciaLocal(atestado, veredito) {
|
|
|
222
235
|
recebidoEm: atestado.recebidoEm, ...veredito };
|
|
223
236
|
return gravarRecibo(atestado.raiz, atestado.thread, nomeDoRecibo(atestado), dados);
|
|
224
237
|
}
|
|
238
|
+
/** RM-059 (T8.1): grava o recibo assinado da nota; o nome sai da conexao e da solicitacao, como no gate. */
|
|
239
|
+
function gravarEvidenciaLocalNota(raiz, dados) {
|
|
240
|
+
const completos = { contrato: exports.CONTRATO_RECIBO_DA_NOTA, ...dados };
|
|
241
|
+
return gravarRecibo(raiz, dados.thread, sha(JSON.stringify([dados.connectionId, dados.requestId])) + '.json', completos);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* RM-059 (T8.1, D12): confere o recibo da nota contra a prova do `preflightMaster` (escrita: sem ele a identidade da
|
|
245
|
+
* nota nativa nao se grava) ou contra um `master_done` ja gravado (auditoria: a prova do caminho, que nao decide se a
|
|
246
|
+
* nota vale). Recibo ausente, adulterado, de outra thread, de outra conexao, de outro host ou com outra nota nao confere.
|
|
247
|
+
*/
|
|
248
|
+
function conferirReciboLocalNota(raiz, thread, campos) {
|
|
249
|
+
try {
|
|
250
|
+
if (campos.por !== exports.IDENTIDADE_DA_NOTA_NATIVA || campos.origem !== 'mcp-local' ||
|
|
251
|
+
(campos.canal !== 'claude-code' && campos.canal !== 'codex'))
|
|
252
|
+
return false;
|
|
253
|
+
const host = campos.canal;
|
|
254
|
+
const pedidoId = campos.notaPedida?.pedidoId;
|
|
255
|
+
if (campos.contratoResposta !== exports.CONTRATO_RECIBO_DA_NOTA || typeof pedidoId !== 'string' ||
|
|
256
|
+
typeof campos.conexao !== 'string' || typeof campos.solicitacao !== 'string' || typeof campos.recebidoEm !== 'string' ||
|
|
257
|
+
!Number.isInteger(campos.score) || typeof campos.justificativa !== 'string' || typeof campos.evidencia !== 'string' ||
|
|
258
|
+
!/^[a-f0-9]{64}$/.test(String(campos.evidenciaSha256 ?? '')) || !/^[a-f0-9]{64}$/.test(String(campos.recibo ?? '')))
|
|
259
|
+
return false;
|
|
260
|
+
const nome = sha(JSON.stringify([campos.conexao, campos.solicitacao])) + '.json';
|
|
261
|
+
if (campos.evidencia !== referencia(thread, nome))
|
|
262
|
+
return false;
|
|
263
|
+
const lido = lerRecibo(raiz, thread, nome);
|
|
264
|
+
const esperado = { contrato: exports.CONTRATO_RECIBO_DA_NOTA, thread, pedidoId, host,
|
|
265
|
+
connectionId: campos.conexao, requestId: campos.solicitacao, recebidoEm: campos.recebidoEm,
|
|
266
|
+
score: campos.score, justificativaSha256: sha(campos.justificativa) };
|
|
267
|
+
const sig = assinatura(chaveLocal(raiz, false), esperado);
|
|
268
|
+
return JSON.stringify(lido.dados) === JSON.stringify(esperado) &&
|
|
269
|
+
(0, node_crypto_1.timingSafeEqual)(Buffer.from(lido.assinatura, 'hex'), Buffer.from(sig, 'hex')) &&
|
|
270
|
+
campos.evidenciaSha256 === sha(lido.bytes) && campos.recibo === sha(lido.assinatura);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
225
276
|
function gravarEvidenciaLocalSessao(atestado, entrega) {
|
|
226
277
|
const dados = { contrato: 'ork.hitl-local-session/v1', thread: atestado.thread,
|
|
227
278
|
pedidoId: atestado.pedidoId, contexto: atestado.contexto, pedidoSha256: atestado.pedidoSha256,
|
package/dist/hitl-local.js
CHANGED
|
@@ -23,7 +23,9 @@ const idValido = (s) => typeof s === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,7
|
|
|
23
23
|
/** O callback é fornecido pelo servidor, nunca pelos argumentos de tools/call. */
|
|
24
24
|
function criarIngressoLocal(raiz, origem, elicitar,
|
|
25
25
|
/** Vinculo do adapter para resposta de SESSAO, fornecido pelo servidor. E o mesmo ponto
|
|
26
|
-
* de injecao que `responderSessao` ja tem; ausente, vale o controle nativo do runtime.
|
|
26
|
+
* de injecao que `responderSessao` ja tem; ausente, vale o controle nativo do runtime.
|
|
27
|
+
* RM-059 (F9): a `caixa` de saida do servidor do dono, por onde a resposta a uma sessao
|
|
28
|
+
* `claude-bg` sai para o Mensageiro de Sessoes; sem ela, essa resposta e recusada antes do dialogo. */
|
|
27
29
|
opcoes = {}) {
|
|
28
30
|
if (!['claude-code', 'codex'].includes(origem.host) || !idValido(origem.connectionId))
|
|
29
31
|
throw new Error('hitl.local.origem-invalida');
|
|
@@ -64,6 +66,13 @@ opcoes = {}) {
|
|
|
64
66
|
throw new Error('hitl.local.pedido-antigo');
|
|
65
67
|
if ((0, hitl_contract_1.estadoDoPedido)(pedido) !== 'aberto')
|
|
66
68
|
throw new Error('hitl.local.pedido-expirado');
|
|
69
|
+
// RM-059 (F9, D4): a resposta que nao vai sair (sessao claude-bg sem Mensageiro vivo) recusa antes do dialogo,
|
|
70
|
+
// para o dono nao digitar uma resposta que ficaria sem quem a leve. Com o envio ja reservado, vale a recusa de
|
|
71
|
+
// sempre (`hitl.channel.delivery-uncertain`), logo abaixo.
|
|
72
|
+
const emEnvio = eventos.some(e => e.tipo === 'session_answer_sending' && e.pedidoId === pedidoId);
|
|
73
|
+
const impedimento = alvo === 'session' && !emEnvio ? (0, hitl_sessions_1.impedimentoDaEntrega)(raiz, threadId, pedido, opcoes.controle, opcoes.caixa) : null;
|
|
74
|
+
if (impedimento)
|
|
75
|
+
throw new Error(impedimento);
|
|
67
76
|
const pedidoSha256 = (0, hitl_local_atestado_1.hashPedidoLocal)(pedido), requestId = (0, node_crypto_1.randomUUID)(), controller = new AbortController();
|
|
68
77
|
let liberarReserva;
|
|
69
78
|
(0, hitl_gates_1.comLockHitl)(raiz, threadId, () => {
|
|
@@ -117,7 +126,7 @@ opcoes = {}) {
|
|
|
117
126
|
try {
|
|
118
127
|
return alvo === 'gate'
|
|
119
128
|
? (0, hitl_gates_1.responderGateLocal)(raiz, threadId, pedidoId, token)
|
|
120
|
-
: (0, hitl_sessions_1.responderSessaoLocal)(raiz, threadId, pedidoId, token, opcoes.controle);
|
|
129
|
+
: (0, hitl_sessions_1.responderSessaoLocal)(raiz, threadId, pedidoId, token, opcoes.controle, opcoes.caixa);
|
|
121
130
|
}
|
|
122
131
|
finally {
|
|
123
132
|
(0, hitl_local_atestado_1.descartarAtestadoLocal)(token);
|
package/dist/hitl-lock.js
CHANGED
|
@@ -85,16 +85,10 @@ function comLockInspecionavel(dir, operacao, executar) {
|
|
|
85
85
|
throw new Error('runtime.unavailable: lock HITL exige flock Linux');
|
|
86
86
|
// Mesmo inode/nome do protocolo legado: writer wx antigo também recusa enquanto existir.
|
|
87
87
|
const file = path.join(dir, '.hitl.lock');
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
catch (e) {
|
|
94
|
-
if (e.code !== 'EEXIST')
|
|
95
|
-
throw e;
|
|
96
|
-
fd = fs.openSync(file, fs.constants.O_RDWR | fs.constants.O_NOFOLLOW);
|
|
97
|
-
}
|
|
88
|
+
// `O_EXCL` abria uma janela no primeiro uso: o criador já tinha publicado o inode, mas ainda não o havia travado
|
|
89
|
+
// nem inicializado; um concorrente podia abrir o arquivo vazio e classificá-lo como legado. Todos abrem o mesmo
|
|
90
|
+
// inode e só interpretam os bytes depois do `flock`, que serializa criação, recuperação e uso normal.
|
|
91
|
+
const fd = fs.openSync(file, fs.constants.O_RDWR | fs.constants.O_CREAT | fs.constants.O_NOFOLLOW, 0o600);
|
|
98
92
|
try {
|
|
99
93
|
const st = fs.fstatSync(fd);
|
|
100
94
|
if (!st.isFile() || st.uid !== process.getuid?.() || st.mode & 0o077 || st.nlink !== 1)
|
|
@@ -108,7 +102,7 @@ function comLockInspecionavel(dir, operacao, executar) {
|
|
|
108
102
|
throw new Error('HITL lock mudou durante aquisição');
|
|
109
103
|
let anterior = null;
|
|
110
104
|
const raw = fs.readFileSync(fd, 'utf8');
|
|
111
|
-
if (
|
|
105
|
+
if (raw !== '') {
|
|
112
106
|
let v;
|
|
113
107
|
try {
|
|
114
108
|
v = JSON.parse(raw);
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.ENV_HITL_VERIFIERS = void 0;
|
|
37
37
|
exports.publicHitlVerifiers = publicHitlVerifiers;
|
|
38
|
+
exports.canVerifyPublicReceipt = canVerifyPublicReceipt;
|
|
38
39
|
exports.publicReceiptAuthority = publicReceiptAuthority;
|
|
39
40
|
exports.publicBindingMatches = publicBindingMatches;
|
|
40
41
|
exports.signPublicReceipt = signPublicReceipt;
|
|
@@ -108,6 +109,16 @@ function publicHitlVerifiers(env = process.env) {
|
|
|
108
109
|
}
|
|
109
110
|
return Object.keys(verifiers).length ? JSON.stringify({ schema: 'ork.hitl-verifiers/v1', verifiers }) : undefined;
|
|
110
111
|
}
|
|
112
|
+
/** O processo consegue reconferir este slot com a chave local ou com o material público herdado, sem expor nenhum dos dois. */
|
|
113
|
+
function canVerifyPublicReceipt(canal, native, env = process.env) {
|
|
114
|
+
try {
|
|
115
|
+
const bundle = publicHitlVerifiers(env);
|
|
116
|
+
return !!bundleSchema.parse(JSON.parse(bundle ?? '{}')).verifiers[slotFor(canal, native)];
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
111
122
|
function publicReceiptAuthority(canal, native) {
|
|
112
123
|
return inherited(process.env)[slotFor(canal, native)];
|
|
113
124
|
}
|