@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,362 @@
|
|
|
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.GRAMATICA_DO_NOCTUM = exports.CONTRATO_TIQUE = exports.CONTRATO_RETRATO_DO_ARCO = exports.CONTRATO_INGRESSO_DO_ARCO = void 0;
|
|
37
|
+
exports.listarArcos = listarArcos;
|
|
38
|
+
exports.arcosVigentes = arcosVigentes;
|
|
39
|
+
exports.aceitarModoNoctum = aceitarModoNoctum;
|
|
40
|
+
exports.ehModoNoctum = ehModoNoctum;
|
|
41
|
+
exports.tagNoctumNoPedido = tagNoctumNoPedido;
|
|
42
|
+
exports.recusaDoModoNaThread = recusaDoModoNaThread;
|
|
43
|
+
exports.responderAoArco = responderAoArco;
|
|
44
|
+
exports.retratoDoArco = retratoDoArco;
|
|
45
|
+
exports.textoDoRetrato = textoDoRetrato;
|
|
46
|
+
exports.tiqueDoArco = tiqueDoArco;
|
|
47
|
+
/**
|
|
48
|
+
* RM-058, fatia N6 (D1, D3, D12 e D13 da ork-rm058n6): o transporte que liga o modo #Noctum.
|
|
49
|
+
*
|
|
50
|
+
* O `#Noctum` é o modo de condução do arco, não de uma thread: as threads do arco são `#Auto`, e a lista delas é a do
|
|
51
|
+
* envelope que o dono autorizou (D1). Por isso `parseModo` e `MODOS_LEGADOS` continuam sem ele (o E9 da N1), e o aceite
|
|
52
|
+
* fica aqui, com estado: com algum arco vigente (autorizado, na janela e não encerrado), o pedido com `#Noctum` é aceito
|
|
53
|
+
* e o host recebe os arcos; sem nenhum, a tag é recusada com `noctum.modo.sem-envelope`, dizendo como abrir um arco. Uma
|
|
54
|
+
* thread nova em modo `#Noctum` nunca é criada: trabalho novo entra no arco por emenda do envelope, com prova nova do dono
|
|
55
|
+
* (`noctum.modo.lista-fechada`), porque item, prioridade e dependências são valores dele.
|
|
56
|
+
*
|
|
57
|
+
* O pedido de abertura chega ao núcleo pelo CLI (`ork noctum propor`), pela ferramenta do MCP (`ork_noctum_propor`) e
|
|
58
|
+
* pelos gateways; proposta não autoriza nada. A autorização e a revogação do dono vêm só por ingresso autenticado: o
|
|
59
|
+
* envelope assinado do gateway (`/ork noctum <arco> autorizar <sha256>` ou `revogar`, entregue a `ork noctum responder`
|
|
60
|
+
* pela entrada, conferido aqui com o `autorizarPeloIngresso` e o `revogarPeloIngresso` da N1) ou o diálogo nativo do host
|
|
61
|
+
* pelo MCP. Argumento de ferramenta e comando de terminal nunca são resposta do dono.
|
|
62
|
+
*
|
|
63
|
+
* O tique (D13) junta, nesta ordem, o fechamento, o vigia da N4 e o relatório (RM-058, integração, D7 da ork-rm058integra):
|
|
64
|
+
* o vigia reconcilia, aplica as paradas e, só com o condutor ausente, dá o passo do despacho; a parada que ele grava fecha
|
|
65
|
+
* o arco no mesmo tique, pelo fechamento, com o motivo `supervisao`. Os testes da N6 ainda passam o passo da N2 no lugar do
|
|
66
|
+
* vigia. É o que o cron do dono chama no piloto; nada aqui instala cron.
|
|
67
|
+
*/
|
|
68
|
+
const fs = __importStar(require("node:fs"));
|
|
69
|
+
const path = __importStar(require("node:path"));
|
|
70
|
+
const estado_thread_1 = require("./estado-thread");
|
|
71
|
+
const horario_1 = require("./horario");
|
|
72
|
+
const modos_1 = require("./modos");
|
|
73
|
+
const noctum_arco_1 = require("./noctum-arco");
|
|
74
|
+
const noctum_envelope_1 = require("./noctum-envelope");
|
|
75
|
+
const noctum_fechamento_1 = require("./noctum-fechamento");
|
|
76
|
+
const noctum_fila_1 = require("./noctum-fila");
|
|
77
|
+
const noctum_medicao_1 = require("./noctum-medicao");
|
|
78
|
+
const noctum_relatorio_1 = require("./noctum-relatorio");
|
|
79
|
+
const noctum_registro_1 = require("./noctum-registro");
|
|
80
|
+
const noctum_supervisao_1 = require("./noctum-supervisao");
|
|
81
|
+
const noctum_vigia_1 = require("./noctum-vigia");
|
|
82
|
+
exports.CONTRATO_INGRESSO_DO_ARCO = 'ork.noctum-ingresso/v1';
|
|
83
|
+
exports.CONTRATO_RETRATO_DO_ARCO = 'ork.noctum-retrato/v1';
|
|
84
|
+
exports.CONTRATO_TIQUE = 'ork.noctum-tique/v1';
|
|
85
|
+
/**
|
|
86
|
+
* D12: a gramática do comando dos gateways, com domicílio aqui. Os ingressos do Telegram do Hermes e do OpenClaw guardam
|
|
87
|
+
* uma cópia, e o teste dos gateways confere que as três continuam iguais. O endereço assinado é `noctum` / `arco:<arco>`.
|
|
88
|
+
*/
|
|
89
|
+
exports.GRAMATICA_DO_NOCTUM = '^/ork noctum ([a-z0-9][a-z0-9-]{0,62}) (autorizar [a-f0-9]{64}|revogar)$';
|
|
90
|
+
/** Os arcos desta raiz de estado, pelos nomes das pastas; os que não têm nome de arco ficam de fora. */
|
|
91
|
+
function listarArcos(raiz) {
|
|
92
|
+
try {
|
|
93
|
+
return fs.readdirSync(path.join((0, estado_thread_1.raizDoEstado)(raiz), '.orkastery', 'noctum', 'arcos')).filter(n => noctum_envelope_1.ID_DO_ARCO.test(n)).sort();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Os arcos vigentes no instante: autorizados, dentro da janela e não encerrados. Arco que não se lê não conta. */
|
|
100
|
+
function arcosVigentes(raiz, quando = new Date().toISOString()) {
|
|
101
|
+
const vigentes = [], ilegiveis = [];
|
|
102
|
+
for (const arco of listarArcos(raiz)) {
|
|
103
|
+
let e;
|
|
104
|
+
try {
|
|
105
|
+
e = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
ilegiveis.push(arco);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (e?.situacao === 'vigente' && e.conteudo && e.versao !== null && e.envelopeSha256) {
|
|
112
|
+
vigentes.push({ arco, versao: e.versao, envelopeSha256: e.envelopeSha256, fim: e.conteudo.janela.fim, fuso: e.conteudo.janela.fuso });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return { vigentes, ilegiveis };
|
|
116
|
+
}
|
|
117
|
+
// RM-057 (resposta curta, D9 da ork-rm057respost): a recusa diz como responder curto, nunca a linha com o hash.
|
|
118
|
+
const COMO_ABRIR = 'abra um arco: proponha o envelope com ork noctum propor --arquivo <envelope.json> (ou a ferramenta ork_noctum_propor) ' +
|
|
119
|
+
'e o dono o autoriza respondendo à pergunta dele com a letra, em reply no Telegram, ou pelo diálogo do host';
|
|
120
|
+
/** D1: o `#Noctum` só vale com algum arco vigente; sem nenhum, a recusa tipada diz como abrir um. */
|
|
121
|
+
function aceitarModoNoctum(raiz, quando = new Date().toISOString()) {
|
|
122
|
+
const { vigentes, ilegiveis } = raiz ? arcosVigentes(raiz, quando) : { vigentes: [], ilegiveis: [] };
|
|
123
|
+
if (vigentes.length)
|
|
124
|
+
return vigentes;
|
|
125
|
+
throw new noctum_envelope_1.RecusaDoArco('noctum.modo.sem-envelope', `#Noctum só vale com um envelope vigente, e nenhum arco deste projeto está vigente` +
|
|
126
|
+
`${ilegiveis.length ? ` (não se leram: ${ilegiveis.join(', ')})` : ''}; ${COMO_ABRIR}`);
|
|
127
|
+
}
|
|
128
|
+
/** A entrada nomeia o modo `#Noctum` (`noctum`, `#Noctum`, `--modo noctum`)? */
|
|
129
|
+
function ehModoNoctum(entrada) {
|
|
130
|
+
return (entrada ?? '').trim().replace(/^--?modo[= ]/i, '').replace(/^#/, '').toLowerCase() === 'noctum';
|
|
131
|
+
}
|
|
132
|
+
/** A primeira #TAG de modo do texto é `#Noctum`? A precedência é a de `extrairTagDoPedido`: a primeira tag vence. */
|
|
133
|
+
function tagNoctumNoPedido(texto) {
|
|
134
|
+
const achada = new RegExp(`#(?:noctum|${modos_1.MODOS_LEGADOS.join('|')})\\b`, 'i').exec(texto);
|
|
135
|
+
return !!achada && achada[0].slice(1).toLowerCase() === 'noctum';
|
|
136
|
+
}
|
|
137
|
+
/** A recusa de `ork thread new --modo noctum`: sem arco vigente, o modo nem vale; com ele, a lista do arco é fechada. */
|
|
138
|
+
function recusaDoModoNaThread(raiz, quando = new Date().toISOString()) {
|
|
139
|
+
try {
|
|
140
|
+
aceitarModoNoctum(raiz, quando);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
if (e instanceof noctum_envelope_1.RecusaDoArco)
|
|
144
|
+
return e;
|
|
145
|
+
throw e;
|
|
146
|
+
}
|
|
147
|
+
return new noctum_envelope_1.RecusaDoArco('noctum.modo.lista-fechada', '#Noctum conduz o arco, não uma thread: as threads do arco são #Auto e vêm da ' +
|
|
148
|
+
'lista do envelope que o dono autorizou; trabalho novo entra por emenda (ork noctum propor com a versão nova), autorizada pelo dono');
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* O ingresso dos gateways: o envelope assinado com `autorizar <sha256>` ou `revogar`, conferido pela N1 no endereço do
|
|
152
|
+
* arco (chave do canal, listas, conta e janela de 60 s). Devolve o recibo tipado que os gateways conferem.
|
|
153
|
+
*/
|
|
154
|
+
function responderAoArco(raiz, arco, envelope, quando = new Date().toISOString()) {
|
|
155
|
+
if (!noctum_envelope_1.ID_DO_ARCO.test(arco))
|
|
156
|
+
throw new noctum_envelope_1.RecusaDoArco('noctum.envelope.invalido', 'identificador de arco inválido');
|
|
157
|
+
const texto = typeof envelope?.resposta === 'string' ? envelope.resposta.trim() : '';
|
|
158
|
+
const autorizar = /^autorizar ([a-f0-9]{64})$/.exec(texto);
|
|
159
|
+
if (!autorizar && texto !== 'revogar') {
|
|
160
|
+
throw new noctum_envelope_1.RecusaDoArco('noctum.origem.sem-prova', 'o texto assinado precisa ser autorizar <sha256> ou revogar');
|
|
161
|
+
}
|
|
162
|
+
const recibo = (e, ato, repetida) => ({ ok: true, contrato: exports.CONTRATO_INGRESSO_DO_ARCO, arco, ato, situacao: e.situacao, versao: e.versao, envelopeSha256: e.envelopeSha256, repetida });
|
|
163
|
+
// O "já valia" é decidido sob o lock do arco: duas entregas do mesmo ato ao mesmo tempo dão uma confirmação só.
|
|
164
|
+
const info = { repetida: false };
|
|
165
|
+
if (autorizar)
|
|
166
|
+
return recibo((0, noctum_arco_1.autorizarPeloIngresso)(raiz, arco, autorizar[1], envelope, quando, info), 'autorizar', info.repetida);
|
|
167
|
+
return recibo((0, noctum_arco_1.revogarPeloIngresso)(raiz, arco, envelope, quando, info), 'revogar', info.repetida);
|
|
168
|
+
}
|
|
169
|
+
/** O retrato do arco no instante: situação, janela, consumo, fila, fechamento, relatório e lacunas. Só lê. */
|
|
170
|
+
function retratoDoArco(carregado, arco, opcoes = {}) {
|
|
171
|
+
const quando = opcoes.quando ?? new Date().toISOString();
|
|
172
|
+
const { raiz } = carregado;
|
|
173
|
+
const estado = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
|
|
174
|
+
if (!estado)
|
|
175
|
+
return null;
|
|
176
|
+
const lacunas = [];
|
|
177
|
+
const conteudo = estado.conteudo;
|
|
178
|
+
let consumo = [];
|
|
179
|
+
let fila = null;
|
|
180
|
+
if (conteudo && estado.autorizadoPor) {
|
|
181
|
+
// As unidades dos tetos só: com todos em sessões, nenhuma transcrição nem rollout é lido para o retrato.
|
|
182
|
+
const medicao = (0, noctum_relatorio_1.medidorDoRelatorio)(opcoes, conteudo)(raiz, estado, quando);
|
|
183
|
+
const o = conteudo.orcamento;
|
|
184
|
+
const linha = (escopo, unidade, teto, c) => ({ escopo, unidade, teto, texto: (0, noctum_medicao_1.textoDoConsumo)(c), valor: c.valor });
|
|
185
|
+
consumo = [linha('do arco', o.arco.unidade, o.arco.valor, (0, noctum_medicao_1.consumoDoEscopoNaUnidade)(medicao, 'arco', o.arco.unidade)),
|
|
186
|
+
...o.porConta.map(s => linha(`da conta ${s.conta}`, s.teto.unidade, s.teto.valor, (0, noctum_medicao_1.consumoDoEscopoNaUnidade)(medicao, { conta: s.conta }, s.teto.unidade))),
|
|
187
|
+
...o.porRuntime.map(s => linha(`do runtime ${s.runtime}`, s.teto.unidade, s.teto.valor, (0, noctum_medicao_1.consumoDoEscopoNaUnidade)(medicao, { runtime: s.runtime }, s.teto.unidade)))];
|
|
188
|
+
try {
|
|
189
|
+
const f = (0, noctum_fechamento_1.trabalhosDoArco)((0, noctum_fila_1.fatosDaFila)(carregado, arco, { quando, maquina: opcoes.maquina, lerReservas: opcoes.lerReservas }));
|
|
190
|
+
fila = { situacao: f.situacao, trabalhos: f.trabalhos.map(t => ({ id: t.id, item: t.item, thread: t.thread, estado: t.estado, fase: t.fase,
|
|
191
|
+
motivo: t.motivo })) };
|
|
192
|
+
lacunas.push(...f.lacunas);
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
if (!(e instanceof noctum_envelope_1.RecusaDoArco))
|
|
196
|
+
throw e;
|
|
197
|
+
lacunas.push(`a fila do arco não pôde ser lida (${e.motivo})`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
let fechamento = null;
|
|
201
|
+
if (estado.encerramento) {
|
|
202
|
+
let paradas = [];
|
|
203
|
+
try {
|
|
204
|
+
const r = (0, noctum_fechamento_1.lerFechamento)(raiz, arco);
|
|
205
|
+
paradas = r.paradas.map(p => (0, noctum_fechamento_1.textoDaParada)(p, r.conferencias));
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
if (!(e instanceof noctum_registro_1.RecusaDoRegistro))
|
|
209
|
+
throw e;
|
|
210
|
+
lacunas.push(`o registro do fechamento não se lê (${e.motivo})`);
|
|
211
|
+
}
|
|
212
|
+
fechamento = { motivo: estado.encerramento.motivo, detalhe: estado.encerramento.detalhe, em: estado.encerramento.em, paradas };
|
|
213
|
+
}
|
|
214
|
+
const relatorio = (0, noctum_relatorio_1.retratoDoRelatorio)(raiz, arco, estado.autorizadoPor ? conteudo : null, quando);
|
|
215
|
+
lacunas.push(...relatorio.lacunas);
|
|
216
|
+
let supervisao = null;
|
|
217
|
+
try {
|
|
218
|
+
supervisao = (0, noctum_relatorio_1.fatosDaSupervisao)(raiz, arco, quando);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
if (!(e instanceof noctum_supervisao_1.RecusaDaSupervisao))
|
|
222
|
+
throw e;
|
|
223
|
+
lacunas.push(`a supervisão do arco não se lê (${e.motivo})`);
|
|
224
|
+
}
|
|
225
|
+
return { contrato: exports.CONTRATO_RETRATO_DO_ARCO, arco, quando, situacao: estado.situacao, versao: estado.versao, envelopeSha256: estado.envelopeSha256,
|
|
226
|
+
janela: conteudo ? { inicio: conteudo.janela.inicio, fim: conteudo.janela.fim, fuso: conteudo.janela.fuso } : null,
|
|
227
|
+
propostaPendente: estado.propostaPendente, consumo, fila, fechamento, relatorio, supervisao, decisoesPendentes: estado.decisoes.length, lacunas };
|
|
228
|
+
}
|
|
229
|
+
/** O retrato em texto para pessoa, em pt-BR, com os horários no fuso da janela. */
|
|
230
|
+
function textoDoRetrato(r) {
|
|
231
|
+
const fuso = r.janela?.fuso;
|
|
232
|
+
// O nome com `formatar` deixa o lint do horário (horario-lint) ver que o campo ISO passa pelo formatador.
|
|
233
|
+
const formatarNoFuso = (iso) => (0, horario_1.formatarDataHora)(iso, { fuso, agora: r.quando, locale: 'pt-BR' });
|
|
234
|
+
const l = [`Arco ${r.arco}: ${r.situacao}${r.versao !== null ? `, versão ${r.versao}` : ''}${r.envelopeSha256 ? `, hash ${r.envelopeSha256.slice(0, 12)}` : ''}`];
|
|
235
|
+
if (r.janela)
|
|
236
|
+
l.push(`Janela de ${formatarNoFuso(r.janela.inicio)} a ${formatarNoFuso(r.janela.fim)} (${r.janela.fuso})`);
|
|
237
|
+
if (r.propostaPendente) {
|
|
238
|
+
l.push(`Proposta ${r.propostaPendente.versao} esperando o dono até ${formatarNoFuso(r.propostaPendente.prazo)}: hash ${r.propostaPendente.envelopeSha256}`);
|
|
239
|
+
}
|
|
240
|
+
if (r.consumo.length)
|
|
241
|
+
l.push('Consumo medido:', ...r.consumo.map(c => ` • teto ${c.escopo}: ${c.texto} de ${c.teto} ${c.unidade}`));
|
|
242
|
+
if (r.fila) {
|
|
243
|
+
l.push(`Fila: ${r.fila.situacao}`, ...r.fila.trabalhos.map(t => ` • ${t.id} (${t.item}): ${t.estado}${t.fase ? `, fase ${t.fase}` : ''}` +
|
|
244
|
+
`${t.thread ? `, thread ${t.thread}` : ''}${t.motivo ? ` (${t.motivo})` : ''}`));
|
|
245
|
+
}
|
|
246
|
+
if (r.fechamento) {
|
|
247
|
+
l.push(`Fechamento: ${r.fechamento.motivo} em ${formatarNoFuso(r.fechamento.em)}: ${r.fechamento.detalhe}`, ...r.fechamento.paradas.map(p => ` • ${p}`));
|
|
248
|
+
}
|
|
249
|
+
else if (r.situacao === 'vigente')
|
|
250
|
+
l.push('Fechamento: o arco segue');
|
|
251
|
+
const rel = r.relatorio;
|
|
252
|
+
if (rel.vencimentoEm) {
|
|
253
|
+
l.push(`Relatório da manhã: vence ${formatarNoFuso(rel.vencimentoEm)} pelo canal ${rel.canal}` +
|
|
254
|
+
(rel.versoes.length ? `; ${rel.versoes.map(v => `versão ${v.versao} ${v.entregue ? 'entregue' : 'sem recibo'}`).join(', ')}` : '; nenhuma versão ainda'));
|
|
255
|
+
}
|
|
256
|
+
const s = r.supervisao;
|
|
257
|
+
if (s && (s.parada || s.isolados.length || s.contasFora.length || s.retomadas?.length || s.sessoesParadas?.length)) {
|
|
258
|
+
l.push('Supervisão:', ...(s.parada ? [` • parada: ${s.parada}`] : []), ...s.isolados.map(i => ` • isolado ${i.trabalho}: ${i.motivo}`), ...s.contasFora.map(c => ` • a conta ${c.conta} saiu do arco: ${c.motivo}`), ...(s.retomadas ?? []).map(x => ` • retomada autorizada: ${x}`), ...(s.sessoesParadas ?? []).map(x => ` • ${x}`));
|
|
259
|
+
}
|
|
260
|
+
if (r.decisoesPendentes)
|
|
261
|
+
l.push(`Decisões do dono no lote: ${r.decisoesPendentes} (ork noctum relatorio ${r.arco})`);
|
|
262
|
+
l.push(...(r.lacunas.length ? ['Lacunas:', ...r.lacunas.map(x => ` • ${x}`)] : ['Lacunas: nenhuma']));
|
|
263
|
+
return l.join('\n');
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* O arco terminal e quieto: nada pendente no log e o relatório entregue, ou a janela de entrega dele (24 h depois do
|
|
267
|
+
* vencimento) acabada, quando o relatório não tenta mais (A3 do CHECK: o canal sem transporte, o terminal nunca mostrado).
|
|
268
|
+
* O vigia não roda mais, e o log dele não cresce.
|
|
269
|
+
*/
|
|
270
|
+
function terminalQuieto(carregado, arco, estado, quando) {
|
|
271
|
+
if (!['expirado', 'revogado', 'encerrado'].includes(estado.situacao))
|
|
272
|
+
return false;
|
|
273
|
+
if (estado.despachos.some(d => d.desfecho === 'pendente'))
|
|
274
|
+
return false;
|
|
275
|
+
try {
|
|
276
|
+
const r = (0, noctum_relatorio_1.retratoDoRelatorio)(carregado.raiz, arco, estado.conteudo, quando);
|
|
277
|
+
if (r.versoes.at(-1)?.entregue === true)
|
|
278
|
+
return true;
|
|
279
|
+
return !!r.vencimentoEm && Date.parse(quando) >= Date.parse(r.vencimentoEm) + noctum_relatorio_1.JANELA_DE_ENTREGA_MS;
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* D13: um tique do arco: o fechamento, o vigia e o relatório, nessa ordem (D7 da ork-rm058integra). O vigia reconcilia e
|
|
287
|
+
* aplica as paradas mesmo no arco que fechou (as reservas em voo); só com o arco vigente, a supervisão sem parada e o
|
|
288
|
+
* condutor ausente ele dá o passo do despacho. Antes da janela, e no arco terminal sem reserva pendente e com o relatório
|
|
289
|
+
* entregue, o vigia não roda. Se o vigia volta com a parada da supervisão, ou o passo encerra pela fila vazia, o
|
|
290
|
+
* fechamento roda de novo no mesmo tique: quem encerra é o fechamento, nunca o vigia. Com o `passo` do teste, ele roda no
|
|
291
|
+
* lugar do vigia, só no arco vigente, como na N6. Arco nunca autorizado recusa: o modo não vale. Cada etapa é isolada: a
|
|
292
|
+
* recusa tipada do fechamento, do vigia ou do passo (o registro do fechamento ou da supervisão adulterado ou ocupado, por
|
|
293
|
+
* exemplo) vira falha do tique, e o relatório da manhã sai assim mesmo; o erro que não é recusa sobe depois do relatório.
|
|
294
|
+
*/
|
|
295
|
+
function tiqueDoArco(carregado, arco, opcoes = {}) {
|
|
296
|
+
const quando = opcoes.quando ?? new Date().toISOString();
|
|
297
|
+
const { raiz } = carregado;
|
|
298
|
+
const estado = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
|
|
299
|
+
if (!estado?.autorizadoPor) {
|
|
300
|
+
throw new noctum_envelope_1.RecusaDoArco('noctum.modo.sem-envelope', `o arco ${arco} nunca foi autorizado pelo dono: o #Noctum não vale; ${COMO_ABRIR}`);
|
|
301
|
+
}
|
|
302
|
+
const deFechamento = { quando, maquina: opcoes.maquina, lerReservas: opcoes.lerReservas, medir: opcoes.medir,
|
|
303
|
+
parar: opcoes.parar, listarSessoes: opcoes.listarSessoes, git: opcoes.git };
|
|
304
|
+
const falhas = [];
|
|
305
|
+
let erro = null;
|
|
306
|
+
const isolada = (etapa, fn) => {
|
|
307
|
+
try {
|
|
308
|
+
return fn();
|
|
309
|
+
}
|
|
310
|
+
catch (e) {
|
|
311
|
+
if (e instanceof noctum_envelope_1.RecusaDoArco || e instanceof noctum_registro_1.RecusaDoRegistro || e instanceof noctum_supervisao_1.RecusaDaSupervisao) {
|
|
312
|
+
falhas.push({ etapa, motivo: e.motivo, detalhe: e.message.slice(0, 300) });
|
|
313
|
+
}
|
|
314
|
+
else
|
|
315
|
+
erro ??= e;
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
const queFalhou = () => {
|
|
320
|
+
let e = null;
|
|
321
|
+
try {
|
|
322
|
+
e = (0, noctum_arco_1.lerArco)(raiz, arco, quando);
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
e = null;
|
|
326
|
+
}
|
|
327
|
+
return { fechado: !!e?.encerramento, agora: false, motivo: e?.encerramento?.motivo ?? null, retrato: null, paradas: [], conferencias: [],
|
|
328
|
+
detalhe: 'o fechamento não terminou neste tique; veja as falhas' };
|
|
329
|
+
};
|
|
330
|
+
let fechamento = isolada('fechamento', () => (0, noctum_fechamento_1.fecharSeDevido)(carregado, arco, deFechamento)) ?? queFalhou();
|
|
331
|
+
let passo = null;
|
|
332
|
+
let vigia = null;
|
|
333
|
+
const agora = erro === null && falhas.length === 0 ? (0, noctum_arco_1.lerArco)(raiz, arco, quando) : null;
|
|
334
|
+
if (opcoes.passo) {
|
|
335
|
+
if (!fechamento.fechado && agora?.situacao === 'vigente') {
|
|
336
|
+
passo = isolada('passo', () => opcoes.passo(carregado, arco, quando));
|
|
337
|
+
if (passo?.acao === 'encerrar')
|
|
338
|
+
fechamento = isolada('fechamento', () => (0, noctum_fechamento_1.fecharSeDevido)(carregado, arco, deFechamento)) ?? queFalhou();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else if (agora && agora.situacao !== 'agendado' && !terminalQuieto(carregado, arco, agora, quando)) {
|
|
342
|
+
const deVigia = { ...opcoes.opcoesDoVigia, quando, maquina: opcoes.maquina ?? opcoes.opcoesDoVigia?.maquina,
|
|
343
|
+
passo: { maquina: opcoes.maquina, lerReservas: opcoes.lerReservas, ...opcoes.opcoesDoPasso, ...opcoes.opcoesDoVigia?.passo } };
|
|
344
|
+
vigia = isolada('vigia', () => (opcoes.vigia ?? noctum_vigia_1.vigiarArco)(carregado, arco, deVigia));
|
|
345
|
+
const doVigia = vigia?.acao === 'tique' ? vigia.passo : null;
|
|
346
|
+
passo = doVigia && doVigia.acao !== 'parado' && doVigia.acao !== 'geracao-vencida' ? doVigia : null;
|
|
347
|
+
if (vigia?.acao === 'tique' && !fechamento.fechado && (vigia.parada || passo?.acao === 'encerrar')) {
|
|
348
|
+
fechamento = isolada('fechamento', () => (0, noctum_fechamento_1.fecharSeDevido)(carregado, arco, deFechamento)) ?? queFalhou();
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
let relatorio;
|
|
352
|
+
try {
|
|
353
|
+
relatorio = (0, noctum_relatorio_1.entregarRelatorioSeDevido)(carregado, arco, { quando, maquina: opcoes.maquina, lerReservas: opcoes.lerReservas,
|
|
354
|
+
medir: opcoes.medir, supervisao: opcoes.supervisao, enviar: opcoes.enviar });
|
|
355
|
+
}
|
|
356
|
+
catch (e) {
|
|
357
|
+
throw erro ?? e;
|
|
358
|
+
}
|
|
359
|
+
if (erro !== null)
|
|
360
|
+
throw erro;
|
|
361
|
+
return { contrato: exports.CONTRATO_TIQUE, arco, quando, fechamento, passo, vigia, relatorio, falhas };
|
|
362
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
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.comoResponderAoArco = comoResponderAoArco;
|
|
37
|
+
exports.entregarPerguntaDoArco = entregarPerguntaDoArco;
|
|
38
|
+
/**
|
|
39
|
+
* RM-057 (resposta curta, D4 da ork-rm057respost): a pergunta do arco #Noctum no canal do dono.
|
|
40
|
+
*
|
|
41
|
+
* A pergunta sai pelo transporte do pulse (`.orkastery/monitor/pulse-host.json`, local, fora do git), o mesmo canal que o
|
|
42
|
+
* onboarding grava para o dono, e entra no lote servido com número: o dono responde "a" ou "sim" em reply, "<código> a"
|
|
43
|
+
* de qualquer chat autorizado, a palavra solta no chat em que ela saiu, ou o número com a letra ("1a"). Sem transporte, a
|
|
44
|
+
* pergunta fica só no terminal de quem propôs. O registro só acontece com o recibo do transporte.
|
|
45
|
+
*/
|
|
46
|
+
const fs = __importStar(require("node:fs"));
|
|
47
|
+
const path = __importStar(require("node:path"));
|
|
48
|
+
const estado_thread_1 = require("./estado-thread");
|
|
49
|
+
const noctum_pergunta_1 = require("./noctum-pergunta");
|
|
50
|
+
const pulse_delivery_1 = require("./pulse-delivery");
|
|
51
|
+
const pulse_resposta_1 = require("./pulse-resposta");
|
|
52
|
+
const transporte_do_canal_1 = require("./transporte-do-canal");
|
|
53
|
+
/**
|
|
54
|
+
* RM-057 (resposta curta, D9 da ork-rm057respost): como o dono responde à pergunta do arco, sem linha para copiar. O
|
|
55
|
+
* `/ork noctum <arco> autorizar <sha256>` dos gateways segue aceito, mas não é mais ensinado.
|
|
56
|
+
*/
|
|
57
|
+
function comoResponderAoArco(p) {
|
|
58
|
+
const ato = p.ato === 'autorizar' ? 'autoriza' : 'revoga';
|
|
59
|
+
// GO-FIX 1 (achados 1 e 2): o reply vale só para a mensagem da pergunta; o texto ensina o que de fato vale. GO-FIX 2
|
|
60
|
+
// (D22): o terminal não grava resposta nenhuma, e o texto diz isso em vez de ensinar a digitar lá.
|
|
61
|
+
return [`Em reply à mensagem da pergunta ${p.codigo} no Telegram, responda com a letra (a ${ato}; b e c não mudam nada)`,
|
|
62
|
+
`De qualquer chat autorizado do Telegram, mande ${p.codigo} a`,
|
|
63
|
+
p.ato === 'autorizar' ? `No Claude Code ou em outro host com diálogo nativo: a janela de confirmação, pela ferramenta ork_noctum_autorizar com o arco ${p.arco}`
|
|
64
|
+
: `No Claude Code ou em outro host com diálogo nativo: a janela de confirmação, pela ferramenta ork_noctum_revogar com o arco ${p.arco}`,
|
|
65
|
+
'Digitar a resposta no terminal não grava nada: o ingresso do terminal está desligado'];
|
|
66
|
+
}
|
|
67
|
+
const semEntrega = (detalhe) => ({ numero: null, entregue: false, jaServida: false, host: null, destino: null, mensagens: [], detalhe });
|
|
68
|
+
/** Entrega a pergunta ao canal do dono, uma vez, com o número no título; a mesma pergunta em aberto não sai de novo. */
|
|
69
|
+
function entregarPerguntaDoArco(raiz, p, opcoes = {}) {
|
|
70
|
+
const quando = opcoes.quando ?? new Date().toISOString();
|
|
71
|
+
const dir = opcoes.estadoDir ?? path.join((0, estado_thread_1.raizDoEstado)(raiz), '.orkastery', 'monitor');
|
|
72
|
+
const arquivo = path.join(dir, 'pulse-host.json');
|
|
73
|
+
if (!fs.existsSync(arquivo))
|
|
74
|
+
return semEntrega('sem transporte do canal (pulse-host.json): a pergunta fica no terminal');
|
|
75
|
+
let config;
|
|
76
|
+
try {
|
|
77
|
+
config = JSON.parse(fs.readFileSync(arquivo, 'utf8'));
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return semEntrega('o transporte do canal não se lê');
|
|
81
|
+
}
|
|
82
|
+
const destinoDo = (host) => host === null ? null
|
|
83
|
+
: [config, ...(Array.isArray(config.alternativos) ? config.alternativos : [])].find(t => (0, transporte_do_canal_1.hostDoTransporte)(t) === host)?.destino ?? null;
|
|
84
|
+
try {
|
|
85
|
+
const r = (0, pulse_resposta_1.servirPerguntaDoArco)(raiz, p, { quando, estadoDir: dir, entregar: numero => {
|
|
86
|
+
const e = (0, pulse_delivery_1.entregarPeloTransporte)(raiz, (0, noctum_pergunta_1.textoDaPerguntaDoArco)(p, 'telegram', { quando, numero }), { dir, oQue: 'noctum-pergunta', quando });
|
|
87
|
+
// GO-FIX 1 (achado 2): os ids da mensagem entregue prendem o reply do dono a ESTA mensagem, e a nenhuma outra.
|
|
88
|
+
return { ok: e.ok, host: e.host, destino: destinoDo(e.host), mensagens: e.mensagens };
|
|
89
|
+
} });
|
|
90
|
+
return { ...r, detalhe: r.entregue ? `entregue pelo ${r.host}` : r.jaServida ? `já tinha saído como a pergunta ${r.numero}`
|
|
91
|
+
: 'o transporte do canal não confirmou a entrega' };
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
return semEntrega(`não consegui entregar a pergunta: ${e.message.replace(/\s+/g, ' ').slice(0, 160)}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ALTERNATIVAS_DE_REVOGAR = exports.ALTERNATIVAS_DE_AUTORIZAR = exports.CONTRATO_PERGUNTA_DO_ARCO = void 0;
|
|
4
|
+
exports.alternativasDaPergunta = alternativasDaPergunta;
|
|
5
|
+
exports.fraseDaPergunta = fraseDaPergunta;
|
|
6
|
+
exports.textoDaPerguntaDoArco = textoDaPerguntaDoArco;
|
|
7
|
+
exports.textoDoDialogoDoArco = textoDoDialogoDoArco;
|
|
8
|
+
exports.detalhesDaPergunta = detalhesDaPergunta;
|
|
9
|
+
exports.escolhaDaPergunta = escolhaDaPergunta;
|
|
10
|
+
exports.opcoesDaPergunta = opcoesDaPergunta;
|
|
11
|
+
/**
|
|
12
|
+
* RM-057 (resposta curta, ork-rm057respost): a pergunta do arco #Noctum ao dono, no contrato curto da RM-048.
|
|
13
|
+
*
|
|
14
|
+
* Até aqui, autorizar um arco exigia copiar `/ork noctum <arco> autorizar <sha256>` no Telegram: uma linha de 90
|
|
15
|
+
* caracteres, só num canal, o que a própria RM-057 proíbe, e duas propostas do piloto venceram assim em 20/10/2026. O
|
|
16
|
+
* dono decidiu: ele aprova onde estiver, com resposta curta. Autorizar e revogar viram perguntas com código curto e três
|
|
17
|
+
* alternativas, uma recomendada; o dono responde "a", "sim", "1a" ou "<código> a", em reply no Telegram, no terminal do
|
|
18
|
+
* Claude Code ou pelo diálogo nativo, e o núcleo resolve contra a pergunta pendente.
|
|
19
|
+
*
|
|
20
|
+
* O hash do envelope continua sendo o que é autorizado: ele mora na pergunta (a proposta do log do arco), nunca na
|
|
21
|
+
* resposta, e a resposta só vale para a pergunta de agora (a proposta que mudou tem outro código).
|
|
22
|
+
*
|
|
23
|
+
* Este módulo é puro: monta a pergunta, o texto e a escolha. Quem guarda a pergunta é o log do arco (`noctum-arco.ts`);
|
|
24
|
+
* quem resolve a resposta contra as pendentes é `noctum-resposta.ts`.
|
|
25
|
+
*/
|
|
26
|
+
const horario_1 = require("./horario");
|
|
27
|
+
const hitl_curto_1 = require("./hitl-curto");
|
|
28
|
+
const hitl_texto_livre_1 = require("./hitl-texto-livre");
|
|
29
|
+
const noctum_envelope_1 = require("./noctum-envelope");
|
|
30
|
+
exports.CONTRATO_PERGUNTA_DO_ARCO = 'ork.noctum-pergunta/v1';
|
|
31
|
+
/** A recomendada é a primeira: a proposta é a que o dono pediu. Só ela age; b e c não gravam nada (D13). */
|
|
32
|
+
exports.ALTERNATIVAS_DE_AUTORIZAR = Object.freeze([
|
|
33
|
+
{ letra: 'a', texto: 'Autorizo', acao: 'aprovar', consequencia: 'o arco passa a valer na janela, com este envelope',
|
|
34
|
+
porque: 'é a proposta pedida, com os valores do envelope; revogar segue valendo a qualquer hora' },
|
|
35
|
+
{ letra: 'b', texto: 'Adiar', acao: 'esperar', consequencia: 'nada muda; a proposta vence no prazo dela' },
|
|
36
|
+
{ letra: 'c', texto: 'Mudar algo', acao: 'recusar', consequencia: 'nada é autorizado; diga o que mudar e uma proposta nova sai' },
|
|
37
|
+
]);
|
|
38
|
+
exports.ALTERNATIVAS_DE_REVOGAR = Object.freeze([
|
|
39
|
+
{ letra: 'a', texto: 'Revogo agora', acao: 'aprovar', consequencia: 'nenhum efeito novo passa, e o arco não reabre',
|
|
40
|
+
porque: 'a revogação foi pedida, e ela é o ato de segurança do arco' },
|
|
41
|
+
{ letra: 'b', texto: 'Manter o arco', acao: 'esperar', consequencia: 'nada muda; o arco segue até o fim da janela' },
|
|
42
|
+
{ letra: 'c', texto: 'Mudar algo', acao: 'recusar', consequencia: 'nada é revogado; diga o que mudar e uma emenda é proposta' },
|
|
43
|
+
]);
|
|
44
|
+
function alternativasDaPergunta(p) {
|
|
45
|
+
return p.ato === 'autorizar' ? exports.ALTERNATIVAS_DE_AUTORIZAR : exports.ALTERNATIVAS_DE_REVOGAR;
|
|
46
|
+
}
|
|
47
|
+
/** A pergunta em uma frase. */
|
|
48
|
+
function fraseDaPergunta(p) {
|
|
49
|
+
return p.ato === 'autorizar' ? `Autorizar o arco ${p.arco} (proposta ${p.versao})?` : `Revogar o arco ${p.arco}?`;
|
|
50
|
+
}
|
|
51
|
+
/** As duas linhas de contexto: o que o dono decide, sem o envelope inteiro (ele fica no detalhe). */
|
|
52
|
+
function corpoDaPergunta(p, quando) {
|
|
53
|
+
const c = p.conteudo;
|
|
54
|
+
if (!c)
|
|
55
|
+
return [];
|
|
56
|
+
const fuso = c.janela.fuso;
|
|
57
|
+
const hora = (iso) => (0, horario_1.formatarHora)(iso, { fuso, agora: quando });
|
|
58
|
+
if (p.ato === 'revogar') {
|
|
59
|
+
return [`Vigente até ${hora(c.janela.fim)} (${fuso}), proposta ${p.versao}`,
|
|
60
|
+
'Revogar nega todo efeito novo na hora; o arco não reabre'];
|
|
61
|
+
}
|
|
62
|
+
const destinos = c.destinos.map(d => `${d.repositorio} (${d.base}): ${d.permissoes.join(', ')}`).join('; ');
|
|
63
|
+
const trabalhos = (0, noctum_envelope_1.envelopeComTrabalhos)(c) ? `; ${c.trabalhos.length} trabalho${c.trabalhos.length === 1 ? '' : 's'}` : '';
|
|
64
|
+
return [`Janela de ${hora(c.janela.inicio)} a ${hora(c.janela.fim)} (${fuso}); ${destinos}`,
|
|
65
|
+
`Teto do arco: ${c.orcamento.arco.valor} ${c.orcamento.arco.unidade}${trabalhos}; relatório às ${c.relatorio.horario} por ` +
|
|
66
|
+
`${c.relatorio.canal}`];
|
|
67
|
+
}
|
|
68
|
+
/** O que está parado e o que acontece sem resposta. Expirar nunca autoriza nem revoga. */
|
|
69
|
+
function travaDaPergunta(p, quando) {
|
|
70
|
+
const prazo = (0, horario_1.formatarHora)(p.prazo, { fuso: p.conteudo?.janela.fuso, agora: quando });
|
|
71
|
+
return p.ato === 'autorizar'
|
|
72
|
+
? `A proposta ${p.versao} vale até ${prazo}. Sem resposta, nada é autorizado.`
|
|
73
|
+
: `A pergunta vale até ${prazo}. Sem resposta, o arco segue como está.`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* O texto da pergunta no canal, no contrato curto: o título com o arco e o código, a pergunta, a trava, duas linhas de
|
|
77
|
+
* contexto, as três alternativas com a recomendada e o porquê, e a linha "responda a, b ou c". Nunca o hash, nunca um
|
|
78
|
+
* comando para copiar. Com o número do lote servido, ele vai na frente do título.
|
|
79
|
+
*/
|
|
80
|
+
function textoDaPerguntaDoArco(p, canal, opcoes) {
|
|
81
|
+
const curto = (0, hitl_curto_1.montarPedidoCurto)({
|
|
82
|
+
thread: null, fase: null, titulo: `arco ${p.arco} · ${p.codigo}`, pergunta: fraseDaPergunta(p), trava: travaDaPergunta(p, opcoes.quando),
|
|
83
|
+
corpo: corpoDaPergunta(p, opcoes.quando), prazo: p.prazo,
|
|
84
|
+
alternativas: alternativasDaPergunta(p).map(a => ({ chave: a.letra, texto: a.texto, consequencia: a.consequencia,
|
|
85
|
+
...(a.porque ? { recomendada: { porque: a.porque } } : {}) })),
|
|
86
|
+
}, { quando: opcoes.quando, responder: { tipo: 'letras', codigo: p.codigo, ...(opcoes.numero ? { numero: opcoes.numero } : {}) } });
|
|
87
|
+
return (0, hitl_curto_1.textoDoPedidoCurto)(curto, canal);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* O texto da pergunta no diálogo nativo do host (D7 da ork-rm057respost): o mesmo contrato curto, com a linha do diálogo no
|
|
91
|
+
* lugar da das letras. O código vai no título quando a pergunta tem um (a proposta de antes da resposta curta não tem).
|
|
92
|
+
*/
|
|
93
|
+
function textoDoDialogoDoArco(p, quando) {
|
|
94
|
+
return (0, hitl_curto_1.textoDoPedidoCurto)((0, hitl_curto_1.montarPedidoCurto)({
|
|
95
|
+
thread: null, fase: null, titulo: p.codigo ? `arco ${p.arco} · ${p.codigo}` : `arco ${p.arco}`, pergunta: fraseDaPergunta(p),
|
|
96
|
+
trava: travaDaPergunta(p, quando), corpo: corpoDaPergunta(p, quando), prazo: p.prazo,
|
|
97
|
+
alternativas: alternativasDaPergunta(p).map(a => ({ chave: a.letra, texto: a.texto, consequencia: a.consequencia,
|
|
98
|
+
...(a.porque ? { recomendada: { porque: a.porque } } : {}) })),
|
|
99
|
+
}, { quando, responder: { tipo: 'dialogo' } }), 'terminal');
|
|
100
|
+
}
|
|
101
|
+
/** O detalhe a um pedido de distância ("<código> detalhes"): o envelope inteiro, com o hash, como o dono o autoriza. */
|
|
102
|
+
function detalhesDaPergunta(p) {
|
|
103
|
+
if (!p.conteudo || !p.envelopeSha256)
|
|
104
|
+
return `A pergunta ${p.codigo} do arco ${p.arco} não tem envelope para mostrar.`;
|
|
105
|
+
return [`Envelope da pergunta ${p.codigo} (arco ${p.arco}, proposta ${p.versao}):`, ...(0, noctum_envelope_1.resumoDoEnvelope)(p.conteudo, p.envelopeSha256)].join('\n');
|
|
106
|
+
}
|
|
107
|
+
/** A escolha pela letra, pelo dígito ou pela palavra do vocabulário fechado, pelas ações. Ambígua volta como ambígua. */
|
|
108
|
+
function escolhaDaPergunta(p, trecho) {
|
|
109
|
+
const alternativas = alternativasDaPergunta(p);
|
|
110
|
+
return (0, hitl_texto_livre_1.resolverTrecho)(trecho, alternativas.map(a => a.acao), alternativas.map(a => a.letra));
|
|
111
|
+
}
|
|
112
|
+
/** As alternativas reais em uma linha, para a resposta que não deu para registrar. */
|
|
113
|
+
function opcoesDaPergunta(p) {
|
|
114
|
+
return alternativasDaPergunta(p).map(a => `${a.letra} (${a.texto})`).join(', ');
|
|
115
|
+
}
|