@orkastery/cli 0.5.6 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/README.md +18 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
- package/adapters/claude-code/README.md +37 -5
- package/adapters/claude-code/agents/ork-check.md +1 -0
- package/adapters/claude-code/agents/ork-go.md +1 -0
- package/adapters/claude-code/agents/ork-goal.md +1 -0
- package/adapters/claude-code/agents/ork-master.md +1 -0
- package/adapters/claude-code/agents/ork-plan.md +1 -0
- package/adapters/claude-code/agents/ork-ship.md +1 -0
- package/adapters/claude-code/hooks/hooks.json +2 -1
- package/adapters/claude-code/hooks/ork-guard.js +15 -1
- package/adapters/claude-code/hooks/ork-resposta.js +91 -0
- package/adapters/claude-code/hooks/ork-sensor.js +18 -2
- package/adapters/claude-code/hooks/quota-signal.js +14 -0
- package/adapters/claude-code/mods/ork-mensageiro/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
- package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
- package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +9 -5
- package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
- package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
- package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +1 -1
- package/adapters/codex/skills/ork/SKILL.md +2 -0
- package/adapters/hermes/README.md +64 -1
- package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
- package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
- package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
- package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
- package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
- package/adapters/hermes/hermes.plugin.json +4 -0
- package/adapters/hermes/hitl-ingress/__init__.py +101 -8
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +2 -2
- package/adapters/openclaw/README.md +81 -9
- package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
- package/adapters/openclaw/dist/hitl-ingress.js +106 -9
- package/adapters/openclaw/dist/index.js +86 -0
- package/adapters/openclaw/openclaw.plugin.json +34 -4
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +103 -9
- package/adapters/openclaw/src/index.ts +94 -0
- package/assets/adapters-en/claude-code/README.md +403 -0
- package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
- package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
- package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
- package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
- package/assets/adapters-en/claude-code/commands/check.md +46 -0
- package/assets/adapters-en/claude-code/commands/go.md +46 -0
- package/assets/adapters-en/claude-code/commands/goal.md +55 -0
- package/assets/adapters-en/claude-code/commands/master.md +54 -0
- package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
- package/assets/adapters-en/claude-code/commands/ork.md +126 -0
- package/assets/adapters-en/claude-code/commands/plan.md +47 -0
- package/assets/adapters-en/claude-code/commands/ship.md +45 -0
- package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
- package/assets/adapters-en/hermes/README.md +273 -0
- package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
- package/assets/references-en/README.md +25 -0
- package/assets/references-en/code-review-axes.md +82 -0
- package/assets/references-en/definition-of-done.md +74 -0
- package/assets/references-en/performance-checklist.md +53 -0
- package/assets/references-en/security-checklist.md +101 -0
- package/assets/references-en/testing-patterns.md +51 -0
- package/assets/security-scan/defaults/.golangci.yml +2 -0
- package/assets/security-scan/defaults/eslint.config.mjs +11 -0
- package/assets/security-scan/defaults/gitleaks.toml +3 -0
- package/assets/security-scan/defaults/ruff.toml +1 -0
- package/assets/security-scan/tools-agil.json +87 -0
- package/assets/security-scan/tools.json +625 -0
- package/assets/skills-en/core/onboarding/SKILL.md +58 -0
- package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
- package/assets/skills-en/core/thread-state/SKILL.md +88 -0
- package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
- package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
- package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
- package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
- package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
- package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
- package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
- package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
- package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
- package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
- package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
- package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
- package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
- package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
- package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
- package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
- package/dist/adapters/claude-bg.js +123 -9
- package/dist/adapters/codex-controller-worker.js +12 -5
- package/dist/adapters/codex-events.js +16 -4
- package/dist/adapters/codex.js +3 -1
- package/dist/adapters/grok-events.js +227 -0
- package/dist/adapters/grok-mcp-servidor.js +612 -0
- package/dist/adapters/grok-mcp.js +178 -0
- package/dist/adapters/grok.js +686 -0
- package/dist/agendador-cpu.js +92 -0
- package/dist/atualizar-branch.js +245 -0
- package/dist/auditoria.js +13 -11
- package/dist/auditrun.js +51 -46
- package/dist/autorizacao-duravel.js +327 -0
- package/dist/board.js +94 -40
- package/dist/branch-de-estado.js +23 -10
- package/dist/busca-semantica.js +7 -5
- package/dist/catalogo.js +2 -1
- package/dist/changelog-reconciliacao.js +290 -0
- package/dist/check-agil.js +528 -0
- package/dist/check-modo.js +41 -0
- package/dist/check-paralelo.js +238 -0
- package/dist/ci.js +248 -45
- package/dist/ciclos.js +8 -6
- package/dist/claim-lint.js +12 -8
- package/dist/claims-conferir.js +47 -39
- package/dist/claims.js +10 -9
- package/dist/company-brain-client.js +10 -3
- package/dist/company-brain-migration.js +11 -5
- package/dist/conducao-batida.js +759 -0
- package/dist/conducao-sentinela.js +25 -8
- package/dist/conducao.js +89 -29
- package/dist/conhecimento-consulta.js +270 -0
- package/dist/conhecimento.js +111 -87
- package/dist/conta-esgotada.js +127 -0
- package/dist/dado-privado.js +816 -0
- package/dist/decisao-autonoma.js +5 -4
- package/dist/demo.js +14 -12
- package/dist/dependencias-da-worktree.js +25 -0
- package/dist/divida.js +38 -36
- package/dist/docs.js +89 -89
- package/dist/doctor-forja.js +343 -0
- package/dist/doctor-pulse-cron.js +113 -1
- package/dist/doctor.js +164 -6
- package/dist/dsn-da-memoria.js +417 -0
- package/dist/entrega-por-mod.js +503 -0
- package/dist/entrega-pr.js +154 -54
- package/dist/esgotamentos.js +13 -11
- package/dist/estado-thread.js +21 -18
- package/dist/evalrunner.js +35 -32
- package/dist/fabrica-batida.js +34 -21
- package/dist/fabrica-estado.js +33 -21
- package/dist/fix.js +21 -19
- package/dist/forja/adaptador.js +6 -0
- package/dist/forja/ambiente-de-ci.js +27 -0
- package/dist/forja/api.js +256 -0
- package/dist/forja/cache.js +89 -0
- package/dist/forja/cli.js +60 -0
- package/dist/forja/contrato.js +9 -0
- package/dist/forja/endereco.js +43 -0
- package/dist/forja/estado.js +22 -0
- package/dist/forja/executor.js +73 -0
- package/dist/forja/github/ci.js +95 -0
- package/dist/forja/github/dono-da-rede.js +18 -0
- package/dist/forja/github/metadados.js +15 -0
- package/dist/forja/github/pedidos.js +200 -0
- package/dist/forja/gitlab/ci.js +141 -0
- package/dist/forja/gitlab/consultas.js +59 -0
- package/dist/forja/gitlab/dono-da-rede.js +43 -0
- package/dist/forja/gitlab/metadados.js +15 -0
- package/dist/forja/gitlab/pedidos-abertos.js +158 -0
- package/dist/forja/gitlab/pedidos.js +141 -0
- package/dist/forja/produtor.js +32 -0
- package/dist/forja/registro.js +31 -0
- package/dist/forja/resolver.js +121 -0
- package/dist/forja/texto.js +13 -0
- package/dist/forja/versao.js +71 -0
- package/dist/forja.js +123 -80
- package/dist/handoff.js +23 -13
- package/dist/hitl-contract.js +46 -43
- package/dist/hitl-curto.js +37 -25
- package/dist/hitl-gates.js +13 -11
- package/dist/hitl-local-receipt.js +51 -0
- package/dist/hitl-local.js +11 -2
- package/dist/hitl-lock.js +5 -11
- package/dist/hitl-public-receipt.js +11 -0
- package/dist/hitl-resumo.js +44 -1
- package/dist/hitl-sessions.js +62 -9
- package/dist/hitl-texto-livre.js +7 -4
- package/dist/hitl.js +34 -31
- package/dist/horario.js +20 -1
- package/dist/hosts.js +104 -134
- package/dist/index.js +864 -554
- package/dist/indice-vetorial.js +14 -12
- package/dist/init.js +11 -2
- package/dist/integracoes-locais.js +4 -0
- package/dist/intelligence-graph-cli.js +123 -69
- package/dist/intelligence-graph-query.js +37 -22
- package/dist/leases.js +19 -18
- package/dist/ledger-stats.js +17 -16
- package/dist/ledger.js +31 -1
- package/dist/licoes.js +12 -11
- package/dist/locale-accounts.js +228 -0
- package/dist/locale-adapter.js +291 -0
- package/dist/locale-ajuda.js +86 -10
- package/dist/locale-audit.js +199 -0
- package/dist/locale-claims.js +213 -0
- package/dist/locale-conducao.js +138 -0
- package/dist/locale-conhecimento.js +181 -0
- package/dist/locale-decisao.js +205 -0
- package/dist/locale-docs.js +230 -0
- package/dist/locale-estado.js +101 -0
- package/dist/locale-forja.js +288 -0
- package/dist/locale-gerados.js +5 -0
- package/dist/locale-grafo.js +129 -0
- package/dist/locale-master.js +83 -0
- package/dist/locale-network.js +524 -0
- package/dist/locale-operacao-restante.js +931 -0
- package/dist/locale-projetos.js +100 -0
- package/dist/locale-prompts.js +194 -0
- package/dist/locale-pulse.js +140 -2
- package/dist/locale-reservas.js +87 -0
- package/dist/locale-retry.js +183 -6
- package/dist/locale-security-scan.js +69 -0
- package/dist/locale-setup.js +192 -0
- package/dist/locale-ship.js +177 -66
- package/dist/locale-thread.js +149 -5
- package/dist/locale-verify.js +80 -4
- package/dist/locale-worktree.js +246 -0
- package/dist/locale.js +553 -9
- package/dist/maestro-runtime.js +22 -3
- package/dist/manifest.js +293 -12
- package/dist/maquina-ociosa.js +211 -0
- package/dist/maquina.js +10 -5
- package/dist/master-nota-local.js +200 -0
- package/dist/master-nota.js +10 -2
- package/dist/master.js +118 -41
- package/dist/mcp-conhecimento.js +52 -0
- package/dist/mcp-experiencia.js +26 -5
- package/dist/mcp-install.js +90 -15
- package/dist/mcp-noctum.js +101 -0
- package/dist/mcp-server.js +116 -22
- package/dist/mcp-ship-transporte.js +977 -0
- package/dist/mcp-ship.js +68 -24
- package/dist/mcp-transportes.js +17 -0
- package/dist/memoria.js +63 -58
- package/dist/merge-da-entrega.js +85 -0
- package/dist/modos-migracao.js +8 -6
- package/dist/modos.js +17 -18
- package/dist/network-roadmap.js +94 -54
- package/dist/noctum-aceite.js +929 -0
- package/dist/noctum-arco.js +540 -33
- package/dist/noctum-capacidade.js +3 -3
- package/dist/noctum-changelog.js +399 -0
- package/dist/noctum-cli.js +539 -0
- package/dist/noctum-coordenacao.js +1225 -0
- package/dist/noctum-entrega.js +1217 -0
- package/dist/noctum-envelope.js +253 -17
- package/dist/noctum-execucao.js +100 -24
- package/dist/noctum-fechamento.js +416 -0
- package/dist/noctum-fila.js +49 -10
- package/dist/noctum-guarda.js +333 -0
- package/dist/noctum-integracao.js +507 -0
- package/dist/noctum-maquinas.js +387 -0
- package/dist/noctum-medicao.js +450 -0
- package/dist/noctum-modo.js +390 -0
- package/dist/noctum-pergunta-canal.js +96 -0
- package/dist/noctum-pergunta.js +115 -0
- package/dist/noctum-provas.js +838 -0
- package/dist/noctum-reconciliacao.js +594 -0
- package/dist/noctum-rede.js +102 -0
- package/dist/noctum-registro.js +215 -0
- package/dist/noctum-relatorio.js +861 -0
- package/dist/noctum-resposta.js +207 -0
- package/dist/noctum-retomada-rede.js +71 -0
- package/dist/noctum-sessoes-em-voo.js +93 -0
- package/dist/noctum-supervisao.js +649 -0
- package/dist/noctum-terminal.js +459 -0
- package/dist/noctum-transporte.js +655 -0
- package/dist/noctum-vigia.js +679 -0
- package/dist/ocupacao.js +3 -1
- package/dist/onboarding.js +16 -5
- package/dist/orkmind.js +39 -23
- package/dist/orquestracao.js +31 -35
- package/dist/parado-no-condutor.js +160 -139
- package/dist/phase.js +96 -42
- package/dist/policies.js +33 -0
- package/dist/postura-local.js +11 -6
- package/dist/preflight.js +2 -1
- package/dist/procedencia.js +9 -14
- package/dist/projeto-alvo.js +59 -20
- package/dist/prompts.js +136 -42
- package/dist/prova-minima.js +5 -6
- package/dist/pulse-cadencia.js +5 -4
- package/dist/pulse-consentimento.js +53 -1
- package/dist/pulse-delivery.js +143 -27
- package/dist/pulse-resposta.js +368 -4
- package/dist/pulse.js +136 -3
- package/dist/ratelimit.js +13 -4
- package/dist/recall.js +14 -13
- package/dist/rede-adesao.js +13 -8
- package/dist/rede-forja.js +108 -24
- package/dist/rede-status.js +63 -45
- package/dist/rede.js +86 -46
- package/dist/retomada-checkpoint.js +101 -0
- package/dist/retry.js +326 -78
- package/dist/roadmap-reservas.js +32 -32
- package/dist/runtime-ambiente.js +5 -0
- package/dist/runtime-context.js +279 -85
- package/dist/runtime-escada.js +429 -0
- package/dist/runtime-profiles.js +130 -63
- package/dist/runtimes.js +42 -5
- package/dist/saida-segura.js +3 -2
- package/dist/security-scan/agil.js +366 -0
- package/dist/security-scan/cli.js +76 -0
- package/dist/security-scan/compare.js +149 -0
- package/dist/security-scan/config.js +93 -0
- package/dist/security-scan/detect.js +97 -0
- package/dist/security-scan/executor.js +196 -0
- package/dist/security-scan/guard.js +180 -0
- package/dist/security-scan/imagem-de-lint.js +96 -0
- package/dist/security-scan/normalize/actionlint.js +12 -0
- package/dist/security-scan/normalize/eslint.js +12 -0
- package/dist/security-scan/normalize/gitleaks.js +13 -0
- package/dist/security-scan/normalize/golangci-lint.js +13 -0
- package/dist/security-scan/normalize/govulncheck.js +36 -0
- package/dist/security-scan/normalize/index.js +25 -0
- package/dist/security-scan/normalize/npm-audit.js +30 -0
- package/dist/security-scan/normalize/osv-scanner.js +32 -0
- package/dist/security-scan/normalize/oxlint.js +51 -0
- package/dist/security-scan/normalize/pip-audit.js +16 -0
- package/dist/security-scan/normalize/ruff.js +12 -0
- package/dist/security-scan/normalize/semgrep.js +20 -0
- package/dist/security-scan/normalize/trivy.js +33 -0
- package/dist/security-scan/normalize/util.js +204 -0
- package/dist/security-scan/normalize/zizmor.js +19 -0
- package/dist/security-scan/report.js +156 -0
- package/dist/security-scan/run.js +448 -0
- package/dist/security-scan/tools.js +62 -0
- package/dist/security-scan/trabalhador.js +74 -0
- package/dist/security-scan/types.js +15 -0
- package/dist/session-events.js +19 -2
- package/dist/session-watcher-claude.js +74 -19
- package/dist/session-watcher-grok.js +425 -0
- package/dist/session-watcher.js +174 -13
- package/dist/sessoes-contas.js +42 -5
- package/dist/sessoes-inventario.js +1 -1
- package/dist/sessoes.js +25 -23
- package/dist/setup.js +67 -66
- package/dist/ship-publicar.js +263 -92
- package/dist/ship.js +160 -17
- package/dist/superficie.js +14 -11
- package/dist/thread-close.js +9 -9
- package/dist/thread.js +121 -18
- package/dist/tokens.js +15 -11
- package/dist/trabalho-thread.js +297 -0
- package/dist/transporte-do-canal.js +189 -0
- package/dist/types.js +12 -1
- package/dist/util.js +5 -2
- package/dist/varredura-acoes.js +500 -0
- package/dist/verify.js +491 -32
- package/dist/worktree-local.js +12 -10
- package/dist/worktree.js +81 -85
- package/eval/casos/check-quality.json +77 -0
- package/eval/casos/security-auditor.json +148 -0
- package/eval/casos/security-remediation.json +161 -0
- package/eval/fixtures/security-scan/README.md +8 -0
- package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/go/Dockerfile +4 -0
- package/eval/fixtures/security-scan/go/README.md +4 -0
- package/eval/fixtures/security-scan/go/config.go +4 -0
- package/eval/fixtures/security-scan/go/go.mod +5 -0
- package/eval/fixtures/security-scan/go/go.sum +2 -0
- package/eval/fixtures/security-scan/go/main.go +31 -0
- package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/js/Dockerfile +3 -0
- package/eval/fixtures/security-scan/js/README.md +4 -0
- package/eval/fixtures/security-scan/js/package-lock.json +844 -0
- package/eval/fixtures/security-scan/js/package.json +10 -0
- package/eval/fixtures/security-scan/js/src/config.js +4 -0
- package/eval/fixtures/security-scan/js/src/server.js +17 -0
- package/eval/fixtures/security-scan/js/src/util.ts +4 -0
- package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
- package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/python/Dockerfile +3 -0
- package/eval/fixtures/security-scan/python/README.md +4 -0
- package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
- package/eval/fixtures/security-scan/python/app/config.py +2 -0
- package/eval/fixtures/security-scan/python/app/main.py +19 -0
- package/eval/fixtures/security-scan/python/requirements.txt +1 -0
- package/package.json +10 -5
- package/references/security-checklist.md +3 -3
- package/skills/README.md +1 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/check-quality/SKILL.md +16 -0
- package/skills/phases/go-implementation/SKILL.md +6 -0
- package/skills/phases/security-remediation/SKILL.md +70 -0
- package/skills/reviewers/security-auditor/SKILL.md +25 -0
package/dist/projeto-alvo.js
CHANGED
|
@@ -41,6 +41,7 @@ exports.raizCanonica = raizCanonica;
|
|
|
41
41
|
exports.remotoSemCredencial = remotoSemCredencial;
|
|
42
42
|
exports.remotoDoProjeto = remotoDoProjeto;
|
|
43
43
|
exports.registrarProjeto = registrarProjeto;
|
|
44
|
+
exports.diretorioEfemero = diretorioEfemero;
|
|
44
45
|
exports.registrarProjetoEmSilencio = registrarProjetoEmSilencio;
|
|
45
46
|
exports.esquecerProjeto = esquecerProjeto;
|
|
46
47
|
exports.candidatosDoHost = candidatosDoHost;
|
|
@@ -87,6 +88,7 @@ const maquina_1 = require("./maquina");
|
|
|
87
88
|
const policies_1 = require("./policies");
|
|
88
89
|
const redacao_url_1 = require("./redacao-url");
|
|
89
90
|
const util_1 = require("./util");
|
|
91
|
+
const locale_1 = require("./locale");
|
|
90
92
|
exports.CONTRATO_PROJETOS = 'ork.projetos/v1';
|
|
91
93
|
exports.CONTRATO_CONSULTA = 'ork.consulta/v1';
|
|
92
94
|
/** O projeto pedido pelo ambiente, abaixo de `--projeto` e acima do cwd. */
|
|
@@ -129,16 +131,18 @@ class ErroDeProjeto extends Error {
|
|
|
129
131
|
return { erro: this.codigo, detalhe: this.detalhe, candidatos: this.candidatos, correcao: this.correcao };
|
|
130
132
|
}
|
|
131
133
|
get texto() {
|
|
134
|
+
const m = (0, locale_1.msg)().projetos;
|
|
132
135
|
return [
|
|
133
136
|
`${this.codigo}: ${this.detalhe}`,
|
|
134
|
-
...(this.candidatos.length ? [
|
|
137
|
+
...(this.candidatos.length ? [m.candidatos, ...this.candidatos.map((c) => ` • ${linhaDoCandidato(c)}`)] : []),
|
|
135
138
|
this.correcao,
|
|
136
139
|
].join('\n');
|
|
137
140
|
}
|
|
138
141
|
}
|
|
139
142
|
exports.ErroDeProjeto = ErroDeProjeto;
|
|
140
143
|
function linhaDoCandidato(c) {
|
|
141
|
-
|
|
144
|
+
const m = (0, locale_1.msg)().projetos;
|
|
145
|
+
return `${c.nome} (${c.abbrev || '-'}) · ${c.raiz} · ${c.remoto ?? m.semRemoto}${c.presente ? '' : ` · ${m.ausente}`}`;
|
|
142
146
|
}
|
|
143
147
|
// ---------------------------------------------------------------------------
|
|
144
148
|
// O registro.
|
|
@@ -250,7 +254,7 @@ function comTrava(alterar, esperaMs = 2000) {
|
|
|
250
254
|
continue;
|
|
251
255
|
}
|
|
252
256
|
if (Date.now() >= limite)
|
|
253
|
-
throw new Error(
|
|
257
|
+
throw new Error((0, locale_1.msg)().projetos.ocupado(trava));
|
|
254
258
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 10);
|
|
255
259
|
}
|
|
256
260
|
}
|
|
@@ -277,7 +281,7 @@ function gravarRegistro(registro) {
|
|
|
277
281
|
const conteudo = JSON.stringify(registro, null, 2) + '\n';
|
|
278
282
|
// Varredura final: o arquivo nunca carrega credencial, nem por um remoto mal redigido.
|
|
279
283
|
if ((0, policies_1.procurarSegredos)(conteudo).length)
|
|
280
|
-
throw new Error(
|
|
284
|
+
throw new Error((0, locale_1.msg)().projetos.segredoConteudo);
|
|
281
285
|
const temp = path.join(dir, `.${ARQUIVO}.${process.pid}.${Date.now()}.tmp`);
|
|
282
286
|
try {
|
|
283
287
|
fs.writeFileSync(temp, conteudo, { mode: 0o600, flag: 'wx' });
|
|
@@ -310,18 +314,18 @@ function projetoDoCaminho(caminho) {
|
|
|
310
314
|
function registrarProjeto(caminho, fonte, opcoes = {}) {
|
|
311
315
|
const achado = projetoDoCaminho(caminho);
|
|
312
316
|
if (!achado) {
|
|
313
|
-
throw new ErroDeProjeto('projeto.sem-manifesto',
|
|
317
|
+
throw new ErroDeProjeto('projeto.sem-manifesto', (0, locale_1.msg)().projetos.semManifesto(raizParaExibir(path.resolve(caminho))), [], (0, locale_1.msg)().projetos.rodeInit);
|
|
314
318
|
}
|
|
315
319
|
const { raiz: canonica, carregado } = achado;
|
|
316
320
|
if (carregado.erros.length)
|
|
317
|
-
throw new Error(
|
|
321
|
+
throw new Error((0, locale_1.msg)().projetos.manifestoInvalido(carregado.caminho));
|
|
318
322
|
const quando = opcoes.quando ?? new Date().toISOString();
|
|
319
323
|
const novo = {
|
|
320
324
|
nome: carregado.manifesto.project.name, abbrev: carregado.manifesto.project.abbrev, raiz: canonica,
|
|
321
325
|
remoto: remotoDoProjeto(canonica, carregado.manifesto.fabrica?.remoto ?? 'origin'), atualizadoEm: quando, fonte,
|
|
322
326
|
};
|
|
323
327
|
if ((0, policies_1.procurarSegredos)(JSON.stringify(novo)).length) {
|
|
324
|
-
throw new Error(
|
|
328
|
+
throw new Error((0, locale_1.msg)().projetos.segredoEntrada);
|
|
325
329
|
}
|
|
326
330
|
return comTrava(() => {
|
|
327
331
|
const registro = lerRegistroDeProjetos();
|
|
@@ -334,16 +338,52 @@ function registrarProjeto(caminho, fonte, opcoes = {}) {
|
|
|
334
338
|
return entrada;
|
|
335
339
|
}, opcoes.esperaMs);
|
|
336
340
|
}
|
|
341
|
+
/** As pastas efemeras desta maquina: a temporaria do sistema e as que o `/tmp` costuma ter. */
|
|
342
|
+
function pastasTemporarias() {
|
|
343
|
+
const raizes = [os.tmpdir(), '/tmp', '/var/tmp', '/dev/shm'];
|
|
344
|
+
const job = (process.env.CLAUDE_JOB_DIR ?? '').trim();
|
|
345
|
+
if (job && path.isAbsolute(job))
|
|
346
|
+
raizes.push(job);
|
|
347
|
+
return [...new Set(raizes.flatMap((r) => { try {
|
|
348
|
+
return [path.resolve(r), fs.realpathSync(r)];
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
return [path.resolve(r)];
|
|
352
|
+
} }))];
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* RM-063 (fatia 3, achado b): o caminho esta numa pasta que some sozinha? A temporaria do sistema (`/tmp`, `TMPDIR`,
|
|
356
|
+
* `/var/tmp`, `/dev/shm`) e a pasta de um job de fundo do Claude Code (`~/.claude*\/jobs/<id>/`, ou `CLAUDE_JOB_DIR`).
|
|
357
|
+
*/
|
|
358
|
+
function diretorioEfemero(caminho) {
|
|
359
|
+
let real = path.resolve(caminho);
|
|
360
|
+
try {
|
|
361
|
+
real = fs.realpathSync(real);
|
|
362
|
+
}
|
|
363
|
+
catch { /* o caminho que ja sumiu vale como foi escrito */ }
|
|
364
|
+
if (/\/\.claude[^/]*\/jobs\/[^/]+(\/|$)/.test(real))
|
|
365
|
+
return true;
|
|
366
|
+
return pastasTemporarias().some((r) => real === r || real.startsWith(r.endsWith(path.sep) ? r : r + path.sep));
|
|
367
|
+
}
|
|
337
368
|
/**
|
|
338
369
|
* D7: o registro nunca derruba o comando que o alimenta. Devolve o aviso para o terminal, ou `null`.
|
|
370
|
+
*
|
|
371
|
+
* RM-063 (fatia 3, achado b): provas e testes que rodam o `ork` em projetos de `/tmp` e da pasta dos jobs do Claude
|
|
372
|
+
* Code encheram o `~/.orkastery/projetos.json` real de projetos que somem. O registro automatico (init, thread new,
|
|
373
|
+
* fabrica entrar) nao grava projeto efemero num registro duravel: o projeto de `/tmp` so entra no registro que tambem
|
|
374
|
+
* e efemero (o `ORKASTERY_HOME` temporario dos testes). `ork projetos registrar`, pedido explicito, continua valendo.
|
|
339
375
|
*/
|
|
340
|
-
function registrarProjetoEmSilencio(raiz, fonte) {
|
|
376
|
+
function registrarProjetoEmSilencio(raiz, fonte, opcoes = {}) {
|
|
377
|
+
const efemero = opcoes.efemero ?? diretorioEfemero;
|
|
341
378
|
try {
|
|
379
|
+
if (efemero(raiz) && !efemero((0, maquina_1.pastaDoUsuario)())) {
|
|
380
|
+
return (0, locale_1.msg)().projetos.avisoTemporario(raizParaExibir(path.resolve(raiz)), caminhoDoRegistro());
|
|
381
|
+
}
|
|
342
382
|
registrarProjeto(raiz, fonte);
|
|
343
383
|
return null;
|
|
344
384
|
}
|
|
345
385
|
catch (e) {
|
|
346
|
-
return
|
|
386
|
+
return (0, locale_1.msg)().projetos.avisoRegistro(caminhoDoRegistro(), e.message);
|
|
347
387
|
}
|
|
348
388
|
}
|
|
349
389
|
/** Tira do registro por nome, abbrev ou caminho. Nada casou e recusa, com os registrados. */
|
|
@@ -354,7 +394,7 @@ function esquecerProjeto(alvo, cwd = process.cwd()) {
|
|
|
354
394
|
const porCaminho = ehCaminho(valor) ? caminhoPossivel(valor, cwd) : null;
|
|
355
395
|
const sai = registro.projetos.filter((p) => porCaminho ? p.raiz === porCaminho : casaNome(p, valor));
|
|
356
396
|
if (!sai.length) {
|
|
357
|
-
throw new ErroDeProjeto('projeto.desconhecido',
|
|
397
|
+
throw new ErroDeProjeto('projeto.desconhecido', (0, locale_1.msg)().projetos.naoRegistrado(valor), registro.projetos.map(candidatoDoRegistro), (0, locale_1.msg)().projetos.vejaRegistrados);
|
|
358
398
|
}
|
|
359
399
|
registro.projetos = registro.projetos.filter((p) => !sai.includes(p));
|
|
360
400
|
registro.atualizadoEm = new Date().toISOString();
|
|
@@ -392,17 +432,17 @@ function candidatoDoRegistro(p) {
|
|
|
392
432
|
function raizPorCaminho(valor, cwd) {
|
|
393
433
|
const dir = path.resolve(cwd, expandirHome(valor));
|
|
394
434
|
if (!fs.existsSync(dir)) {
|
|
395
|
-
throw new ErroDeProjeto('projeto.sem-manifesto',
|
|
435
|
+
throw new ErroDeProjeto('projeto.sem-manifesto', (0, locale_1.msg)().projetos.caminhoNaoExiste(raizParaExibir(dir)), [], (0, locale_1.msg)().projetos.informeRaiz);
|
|
396
436
|
}
|
|
397
437
|
const achada = (0, util_1.subirAte)(dir, manifest_1.NOME_MANIFESTO) ?? (0, util_1.subirAte)(dir, manifest_1.NOME_MANIFESTO_LEGADO);
|
|
398
438
|
if (!achada) {
|
|
399
|
-
throw new ErroDeProjeto('projeto.sem-manifesto',
|
|
439
|
+
throw new ErroDeProjeto('projeto.sem-manifesto', (0, locale_1.msg)().projetos.yamlAusente(raizParaExibir(dir)), [], (0, locale_1.msg)().projetos.initOuNome);
|
|
400
440
|
}
|
|
401
441
|
return fs.realpathSync(achada);
|
|
402
442
|
}
|
|
403
443
|
function raizPorNome(valor) {
|
|
404
444
|
if (!exports.PADRAO_DO_NOME_DE_PROJETO.test(valor)) {
|
|
405
|
-
throw new ErroDeProjeto('projeto.desconhecido',
|
|
445
|
+
throw new ErroDeProjeto('projeto.desconhecido', (0, locale_1.msg)().projetos.nomeInvalido(valor), lerRegistroDeProjetos().projetos.map(candidatoDoRegistro), (0, locale_1.msg)().projetos.useNome);
|
|
406
446
|
}
|
|
407
447
|
const registrados = lerRegistroDeProjetos().projetos;
|
|
408
448
|
const casados = registrados.filter((p) => casaNome(p, valor));
|
|
@@ -410,9 +450,9 @@ function raizPorNome(valor) {
|
|
|
410
450
|
if (presentes.length === 1)
|
|
411
451
|
return presentes[0].raiz;
|
|
412
452
|
if (presentes.length > 1) {
|
|
413
|
-
throw new ErroDeProjeto('projeto.ambiguo',
|
|
453
|
+
throw new ErroDeProjeto('projeto.ambiguo', (0, locale_1.msg)().projetos.ambiguo(valor, presentes.length), presentes.map(candidatoDoRegistro), (0, locale_1.msg)().projetos.escolhaRaiz);
|
|
414
454
|
}
|
|
415
|
-
throw new ErroDeProjeto('projeto.desconhecido', casados.length ?
|
|
455
|
+
throw new ErroDeProjeto('projeto.desconhecido', casados.length ? (0, locale_1.msg)().projetos.semManifestoRegistrado(valor) : (0, locale_1.msg)().projetos.naoRegistrado(valor), registrados.map(candidatoDoRegistro), (0, locale_1.msg)().projetos.registreCopia);
|
|
416
456
|
}
|
|
417
457
|
/**
|
|
418
458
|
* F2 do CHECK: o nome aponta a arvore principal; quem ja esta numa copia DESSE projeto (a worktree de
|
|
@@ -467,12 +507,12 @@ function resolverProjetoAlvo(entrada = {}) {
|
|
|
467
507
|
if (entrada.opcao !== undefined && entrada.opcao !== null) {
|
|
468
508
|
const valor = entrada.opcao.trim();
|
|
469
509
|
if (!valor) {
|
|
470
|
-
throw new ErroDeProjeto('projeto.desconhecido',
|
|
510
|
+
throw new ErroDeProjeto('projeto.desconhecido', (0, locale_1.msg)().projetos.opcaoSemValor, lerRegistroDeProjetos().projetos.map(candidatoDoRegistro), (0, locale_1.msg)().projetos.usoOpcao);
|
|
471
511
|
}
|
|
472
512
|
// D4 (F1 do CHECK): no host, quem pede escolhe entre os projetos da maquina pelo NOME. Caminho nao
|
|
473
513
|
// entra por nenhuma tool, nem pela que repassa os argumentos como dados (os scripts do Hermes).
|
|
474
514
|
if (host && ehCaminho(valor)) {
|
|
475
|
-
throw new ErroDeProjeto('projeto.desconhecido',
|
|
515
|
+
throw new ErroDeProjeto('projeto.desconhecido', (0, locale_1.msg)().projetos.hostCaminho(valor), lerRegistroDeProjetos().projetos.map(candidatoDoRegistro), (0, locale_1.msg)().projetos.hostUseNome);
|
|
476
516
|
}
|
|
477
517
|
return { raiz: resolverValor(valor, cwd), origem: 'opcao', pedido: valor };
|
|
478
518
|
}
|
|
@@ -484,10 +524,9 @@ function resolverProjetoAlvo(entrada = {}) {
|
|
|
484
524
|
if (candidatos.length === 1)
|
|
485
525
|
return { raiz: copiaDoCwd(candidatos[0].raiz, cwd), origem: 'unico-conhecido', pedido: null };
|
|
486
526
|
if (candidatos.length > 1) {
|
|
487
|
-
throw new ErroDeProjeto('projeto.escolha',
|
|
527
|
+
throw new ErroDeProjeto('projeto.escolha', (0, locale_1.msg)().projetos.precisaEscolher(candidatos.length), candidatos.map((c) => c.candidato), (0, locale_1.msg)().projetos.repitaEscolha((0, locale_1.msg)().projetos.ofertaRede));
|
|
488
528
|
}
|
|
489
|
-
throw new ErroDeProjeto('projeto.nenhum',
|
|
490
|
-
'Sem clone nesta máquina, o roadmap de um projeto vem da forja: `ork network roadmap --projeto github:dono/repo` (tool ork_network_roadmap).');
|
|
529
|
+
throw new ErroDeProjeto('projeto.nenhum', (0, locale_1.msg)().projetos.nenhum, [], (0, locale_1.msg)().projetos.registrePrimeiro);
|
|
491
530
|
}
|
|
492
531
|
return null;
|
|
493
532
|
}
|
package/dist/prompts.js
CHANGED
|
@@ -49,7 +49,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
49
49
|
};
|
|
50
50
|
})();
|
|
51
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
-
exports.TEMPLATES_EMBUTIDOS = exports.TEMPLATE_FASE_PADRAO = exports.PADROES_DE_HITL_EM_TEXTO_LIVRE = exports.CONTRATO_DE_FASE = exports.REGRA_CENTRAL = exports.SECOES_OBRIGATORIAS = exports.LIMITE_TEMPLATE_BYTES = void 0;
|
|
52
|
+
exports.TEMPLATES_EMBUTIDOS = exports.TEMPLATE_FASE_PADRAO_EN = exports.TEMPLATE_FASE_PADRAO = exports.PADROES_DE_HITL_EM_TEXTO_LIVRE = exports.CONTRATO_DE_FASE_EN = exports.CONTRATO_DE_FASE = exports.REGRA_CENTRAL_EN = exports.SECOES_OBRIGATORIAS_EN = exports.REGRA_CENTRAL = exports.SECOES_OBRIGATORIAS = exports.LIMITE_TEMPLATE_BYTES = void 0;
|
|
53
53
|
exports.pedidoComDicaDoGrafo = pedidoComDicaDoGrafo;
|
|
54
54
|
exports.dirDeTemplates = dirDeTemplates;
|
|
55
55
|
exports.variaveisUsadas = variaveisUsadas;
|
|
@@ -61,6 +61,8 @@ exports.carregarTemplatesDe = carregarTemplatesDe;
|
|
|
61
61
|
exports.carregarTemplates = carregarTemplates;
|
|
62
62
|
exports.exigirTemplate = exigirTemplate;
|
|
63
63
|
exports.templateDaFase = templateDaFase;
|
|
64
|
+
exports.idiomaDoTemplate = idiomaDoTemplate;
|
|
65
|
+
exports.avisosDeLingua = avisosDeLingua;
|
|
64
66
|
exports.textoDoLint = textoDoLint;
|
|
65
67
|
exports.tabelaDeTemplates = tabelaDeTemplates;
|
|
66
68
|
exports.threadDeExemplo = threadDeExemplo;
|
|
@@ -69,20 +71,18 @@ const path = __importStar(require("node:path"));
|
|
|
69
71
|
const modos_1 = require("./modos");
|
|
70
72
|
const policies_1 = require("./policies");
|
|
71
73
|
const types_1 = require("./types");
|
|
74
|
+
const locale_1 = require("./locale");
|
|
75
|
+
const locale_prompts_1 = require("./locale-prompts");
|
|
72
76
|
/** Limite duro de um template, o mesmo do manifesto: prosa longa nao vira prompt. */
|
|
73
77
|
exports.LIMITE_TEMPLATE_BYTES = 16384;
|
|
74
78
|
/**
|
|
75
79
|
* KG5 fatia 2: dica opt-in no pedido; desligada preserva o texto byte a byte. Fatia 5: a dica diz o que
|
|
76
80
|
* a marca `arvore: modificada` quer dizer na aresta.
|
|
77
81
|
*/
|
|
78
|
-
function pedidoComDicaDoGrafo(pedido, thread, ligado) {
|
|
82
|
+
function pedidoComDicaDoGrafo(pedido, thread, ligado, locale = (0, locale_1.localeAtivo)()) {
|
|
79
83
|
if (!ligado)
|
|
80
84
|
return pedido;
|
|
81
|
-
return pedido.trimEnd() + '
|
|
82
|
-
+ `Consulte ork_grafo_contexto {threadId: "${thread}"} ou ork grafo contexto ${thread} --json para o pacote da thread com evidencias e teto em bytes.\n`
|
|
83
|
-
+ 'As tools ork_grafo_vizinhos, ork_grafo_chamadores, ork_grafo_importadores e ork_grafo_caminho permitem aprofundar. '
|
|
84
|
-
+ 'Sem indice do HEAD, rode ork grafo indexar. O grafo e parcial e descreve o HEAD; '
|
|
85
|
-
+ 'aresta com arvore: modificada vem de fonte que mudou depois dele: confira o arquivo antes de usar.\n';
|
|
85
|
+
return pedido.trimEnd() + (locale === 'en' ? locale_prompts_1.PROMPTS_EN : locale_prompts_1.PROMPTS_PT_BR).contextoDoGrafo(thread);
|
|
86
86
|
}
|
|
87
87
|
/** Onde um projeto guarda os templates que sobrescrevem os embutidos. */
|
|
88
88
|
function dirDeTemplates(raiz) {
|
|
@@ -110,7 +110,7 @@ function variaveisUsadas(corpo) {
|
|
|
110
110
|
function renderizar(template, valores) {
|
|
111
111
|
const faltando = variaveisUsadas(template.corpo).filter((v) => !(v in valores));
|
|
112
112
|
if (faltando.length > 0) {
|
|
113
|
-
throw new Error(
|
|
113
|
+
throw new Error((0, locale_1.msg)().prompts.cli.variavelSemValor(template.id, faltando.join(', ')));
|
|
114
114
|
}
|
|
115
115
|
const linhas = template.corpo.split('\n');
|
|
116
116
|
const saida = [];
|
|
@@ -141,7 +141,7 @@ function parseListaInline(bruto) {
|
|
|
141
141
|
function parseTemplate(bruto, origem) {
|
|
142
142
|
const casado = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/.exec(bruto);
|
|
143
143
|
if (!casado) {
|
|
144
|
-
throw new Error(
|
|
144
|
+
throw new Error((0, locale_1.msg)().prompts.cli.frontmatterAusente(origem));
|
|
145
145
|
}
|
|
146
146
|
const campos = {};
|
|
147
147
|
for (const linha of casado[1].split('\n')) {
|
|
@@ -177,6 +177,8 @@ exports.SECOES_OBRIGATORIAS = [
|
|
|
177
177
|
];
|
|
178
178
|
/** A frase que nenhum template pode perder, porque ela e o contrato de todo modo. */
|
|
179
179
|
exports.REGRA_CENTRAL = 'REGRA CENTRAL: o modo afrouxa a pausa, NUNCA a verificacao.';
|
|
180
|
+
exports.SECOES_OBRIGATORIAS_EN = locale_prompts_1.PROMPTS_EN.secoesObrigatorias;
|
|
181
|
+
exports.REGRA_CENTRAL_EN = locale_prompts_1.PROMPTS_EN.regraCentral;
|
|
180
182
|
/** O contrato do prompt de fase (o do B4). */
|
|
181
183
|
exports.CONTRATO_DE_FASE = {
|
|
182
184
|
nome: 'fase',
|
|
@@ -185,6 +187,10 @@ exports.CONTRATO_DE_FASE = {
|
|
|
185
187
|
variavelObrigatoria: 'pedido',
|
|
186
188
|
validaFases: true,
|
|
187
189
|
};
|
|
190
|
+
exports.CONTRATO_DE_FASE_EN = {
|
|
191
|
+
nome: 'phase', secoes: exports.SECOES_OBRIGATORIAS_EN, regraCentral: exports.REGRA_CENTRAL_EN,
|
|
192
|
+
variavelObrigatoria: 'pedido', validaFases: true,
|
|
193
|
+
};
|
|
188
194
|
/**
|
|
189
195
|
* RM-057: os jeitos de um template pedir ao dono texto livre ou texto colado. Lista fechada, como o
|
|
190
196
|
* vocabulario do pulse: acrescentar um padrao e decisao de contrato, com teste. Casa sobre a linha
|
|
@@ -213,7 +219,9 @@ function procurarHitlEmTextoLivre(corpo) {
|
|
|
213
219
|
* template que perdeu a regra dos modos, que esqueceu o pedido do builder, que declara variavel
|
|
214
220
|
* que nao usa (ou usa variavel que nao declara) e que carrega credencial.
|
|
215
221
|
*/
|
|
216
|
-
function lintTemplate(t, contrato
|
|
222
|
+
function lintTemplate(t, contrato) {
|
|
223
|
+
contrato ??= t.id.endsWith('.en') ? exports.CONTRATO_DE_FASE_EN : exports.CONTRATO_DE_FASE;
|
|
224
|
+
const mc = (0, locale_1.msg)().prompts.cli;
|
|
217
225
|
const problemas = [];
|
|
218
226
|
const erro = (regra, detalhe) => {
|
|
219
227
|
problemas.push({ template: t.id || t.origem, regra, gravidade: 'erro', detalhe });
|
|
@@ -222,56 +230,56 @@ function lintTemplate(t, contrato = exports.CONTRATO_DE_FASE) {
|
|
|
222
230
|
problemas.push({ template: t.id || t.origem, regra, gravidade: 'aviso', detalhe });
|
|
223
231
|
};
|
|
224
232
|
if (!t.id)
|
|
225
|
-
erro('id',
|
|
233
|
+
erro('id', mc.idAusente);
|
|
226
234
|
if (t.origem !== 'embutido') {
|
|
227
235
|
const esperado = path.basename(t.origem, '.md');
|
|
228
236
|
if (t.id && t.id !== esperado) {
|
|
229
|
-
erro('id',
|
|
237
|
+
erro('id', mc.idDiverge(t.id, esperado));
|
|
230
238
|
}
|
|
231
239
|
}
|
|
232
240
|
if (!Number.isInteger(t.versao) || t.versao < 1) {
|
|
233
|
-
erro('versao',
|
|
241
|
+
erro('versao', mc.versaoInvalida(t.versao));
|
|
234
242
|
}
|
|
235
243
|
if (t.descricao.trim() === '')
|
|
236
|
-
erro('descricao',
|
|
244
|
+
erro('descricao', mc.descricaoAusente);
|
|
237
245
|
if (contrato.validaFases) {
|
|
238
246
|
for (const fase of t.fases) {
|
|
239
247
|
if (!types_1.FASES.includes(fase)) {
|
|
240
|
-
erro('fases',
|
|
248
|
+
erro('fases', mc.faseInvalida(fase, types_1.FASES.join(', ')));
|
|
241
249
|
}
|
|
242
250
|
}
|
|
243
251
|
}
|
|
244
252
|
const usadas = variaveisUsadas(t.corpo);
|
|
245
253
|
const naoDeclaradas = usadas.filter((v) => !t.variaveis.includes(v));
|
|
246
254
|
if (naoDeclaradas.length > 0) {
|
|
247
|
-
erro('variaveis',
|
|
255
|
+
erro('variaveis', mc.variaveisNaoDeclaradas(naoDeclaradas.join(', ')));
|
|
248
256
|
}
|
|
249
257
|
const naoUsadas = t.variaveis.filter((v) => !usadas.includes(v));
|
|
250
258
|
if (naoUsadas.length > 0) {
|
|
251
|
-
erro('variaveis',
|
|
259
|
+
erro('variaveis', mc.variaveisNaoUsadas(naoUsadas.join(', ')));
|
|
252
260
|
}
|
|
253
261
|
for (const secao of contrato.secoes) {
|
|
254
262
|
if (!t.corpo.includes(secao))
|
|
255
|
-
erro('secoes',
|
|
263
|
+
erro('secoes', mc.secaoAusente(secao));
|
|
256
264
|
}
|
|
257
265
|
if (!t.corpo.includes(contrato.regraCentral)) {
|
|
258
|
-
erro('regra-central',
|
|
266
|
+
erro('regra-central', mc.regraCentralAusente(contrato.regraCentral));
|
|
259
267
|
}
|
|
260
268
|
if (contrato.variavelObrigatoria && !usadas.includes(contrato.variavelObrigatoria)) {
|
|
261
|
-
erro(contrato.variavelObrigatoria,
|
|
269
|
+
erro(contrato.variavelObrigatoria, mc.pedidoAusente(contrato.variavelObrigatoria, contrato.nome));
|
|
262
270
|
}
|
|
263
271
|
for (const achado of (0, policies_1.procurarSegredos)(t.bruto)) {
|
|
264
|
-
erro('segredo',
|
|
272
|
+
erro('segredo', mc.segredo(achado.nome, achado.linha));
|
|
265
273
|
}
|
|
266
274
|
const bytes = Buffer.byteLength(t.bruto, 'utf8');
|
|
267
275
|
if (bytes > exports.LIMITE_TEMPLATE_BYTES) {
|
|
268
|
-
erro('tamanho',
|
|
276
|
+
erro('tamanho', mc.tamanho(bytes, exports.LIMITE_TEMPLATE_BYTES));
|
|
269
277
|
}
|
|
270
278
|
for (const achado of procurarHitlEmTextoLivre(t.corpo)) {
|
|
271
|
-
erro('hitl-texto-livre',
|
|
279
|
+
erro('hitl-texto-livre', mc.hitlTextoLivre(achado.linha, achado.oQue));
|
|
272
280
|
}
|
|
273
281
|
if (t.bruto.includes('—')) {
|
|
274
|
-
aviso('idioma',
|
|
282
|
+
aviso('idioma', mc.travessao);
|
|
275
283
|
}
|
|
276
284
|
return problemas;
|
|
277
285
|
}
|
|
@@ -284,10 +292,10 @@ function lintTemplate(t, contrato = exports.CONTRATO_DE_FASE) {
|
|
|
284
292
|
*/
|
|
285
293
|
exports.TEMPLATE_FASE_PADRAO = `---
|
|
286
294
|
id: fase-padrao
|
|
287
|
-
versao:
|
|
295
|
+
versao: 4
|
|
288
296
|
descricao: Prompt canonico de uma fase do ciclo GOAL..MASTER, com nomenclatura, modo de conducao, contexto da thread, memoria injetada e regras de evidencia.
|
|
289
297
|
fases: [GOAL, PLAN, GO, CHECK, SHIP, MASTER]
|
|
290
|
-
variaveis: [fase, thread, bloco, nome, ciclo_canonico, tag, blocos, pausas, linha_variante, regra_de_pausa, invariantes, slug, projeto_nome, projeto_abbrev, base_branch, base_commit, diretorio, pedido, memoria_injetada, regras_de_evidencia]
|
|
298
|
+
variaveis: [fase, thread, bloco, nome, ciclo_canonico, tag, blocos, pausas, linha_variante, regra_de_pausa, invariantes, slug, projeto_nome, projeto_abbrev, base_branch, base_commit, diretorio, trabalho, pedido, fecho_go, memoria_injetada, regras_de_evidencia]
|
|
291
299
|
---
|
|
292
300
|
# Orkastery, fase {{fase}} da thread {{thread}}
|
|
293
301
|
|
|
@@ -321,12 +329,14 @@ REGRA CENTRAL: o modo afrouxa a pausa, NUNCA a verificacao.
|
|
|
321
329
|
- projeto: {{projeto_nome}} (abbrev {{projeto_abbrev}})
|
|
322
330
|
- base carimbada: {{base_branch}} @ {{base_commit}}
|
|
323
331
|
- diretorio de trabalho: {{diretorio}}
|
|
332
|
+
- trabalho retomavel: {{trabalho}} (rascunhos de check e PR, pareceres e listas de prova)
|
|
324
333
|
- estado da thread: .orkastery/threads/{{thread}}/thread.json
|
|
325
334
|
- ledger: .orkastery/threads/{{thread}}/ledger.jsonl
|
|
326
335
|
|
|
327
336
|
## Pedido do builder
|
|
328
337
|
{{pedido}}
|
|
329
338
|
{{memoria_injetada}}
|
|
339
|
+
{{fecho_go}}
|
|
330
340
|
|
|
331
341
|
## Isolamento por sessão
|
|
332
342
|
|
|
@@ -338,9 +348,69 @@ Falha de autenticação permanece impedimento; não troque provider, sandbox ou
|
|
|
338
348
|
|
|
339
349
|
## Regras de evidencia
|
|
340
350
|
{{regras_de_evidencia}}`;
|
|
351
|
+
/** English counterpart of the canonical phase prompt. The pt-BR template above remains the source contract. */
|
|
352
|
+
exports.TEMPLATE_FASE_PADRAO_EN = `---
|
|
353
|
+
id: fase-padrao.en
|
|
354
|
+
versao: 4
|
|
355
|
+
descricao: Canonical prompt for a GOAL..MASTER cycle phase, with naming, conduction mode, thread context, injected memory, and evidence rules.
|
|
356
|
+
fases: [GOAL, PLAN, GO, CHECK, SHIP, MASTER]
|
|
357
|
+
variaveis: [fase, thread, bloco, nome, ciclo_canonico, tag, blocos, pausas, linha_variante, regra_de_pausa, invariantes, slug, projeto_nome, projeto_abbrev, base_branch, base_commit, diretorio, trabalho, pedido, fecho_go, memoria_injetada, regras_de_evidencia]
|
|
358
|
+
---
|
|
359
|
+
# Orkastery, {{fase}} phase of thread {{thread}}
|
|
360
|
+
|
|
361
|
+
You conduct block {{bloco}} of thread "{{nome}}". {{fase}} is the entry phase, not a new orchestration.
|
|
362
|
+
Run the phases in this block in canonical order, respecting each phase scope and the core gates; GOAL does not implement before GO.
|
|
363
|
+
Do not open another thread or redispatch yourself. If the project has an MCP server, prefer its tools for supported state and operations.
|
|
364
|
+
In Claude with the \`orkastery\` server, use the exposed full names: \`ToolSearch\` with \`select:mcp__orkastery__ork_thread_status,mcp__orkastery__ork_artifact_read\` discovers those reads; select the full name for any other tool. Do not search for \`select:ork_thread_status\`. Other hosts use their discovered namespace.
|
|
365
|
+
When available, use ork_artifact_read/write for the goal, plan, and review, and ork_claims_list/ork_claim_add for claims; do not write the ledger or canonical state directly.
|
|
366
|
+
Record every decision you make without asking the owner in the ledger with \`ork decisao registrar <thread>\` (or \`ork_decision_record\` in MCP because the Codex sandbox cannot write the ledger), including what was decided, why, how to change it, reversal cost now and later, the written criterion, who decided, and the evidence. This is how it reaches the owner in the summary instead of disappearing in the conversation.
|
|
367
|
+
An agent-authored artifact is not an official receipt; registering a claim does not verify it.
|
|
368
|
+
To record product changes, prefer ork_git_commit with the current HEAD and paths with claims; use ork_verify for real verification and ork_ship with checked source/destination HEADs for delivery. A local commit is not SHIP; an incomplete result requires reconciling state and remote before retrying. Permission to query does not grant those operations: respect native authorization and gates.
|
|
369
|
+
The conducting session presents an owner decision to the host; a child session neither answers nor assumes the owner's identity.
|
|
370
|
+
Preserve the configured child profile: \`interactive\` grants queries; \`worktree\` requires installation opt-in and authorizes exact tools in the validated worktree, without approving gates or assuming the owner. Do not change configuration to bypass a block.
|
|
371
|
+
Query \`ork_git_status\` for real HEADs and Git state; use \`ork_git_commit\`, \`ork_verify\`, and \`ork_ship\` through the core contracts, without Bash Git or invented SHAs. Use \`source.head\` as the commit \`expectedHead\`; query again after the commit and use \`source.head\`/\`destination.head\` as SHIP \`expectedSource\`/\`expectedDestination\`. A historical base does not replace the current query. Edit/deny rules are native tool permissions, not process sandbox rules.
|
|
372
|
+
A native permission failure or an operation without supported transport remains a real blocker, never a reason to alter the sandbox.
|
|
373
|
+
|
|
374
|
+
## Canonical cycle
|
|
375
|
+
{{ciclo_canonico}}
|
|
376
|
+
|
|
377
|
+
## Conduction mode: {{tag}}
|
|
378
|
+
Blocks in this thread: {{blocos}}
|
|
379
|
+
Human pauses in this thread: {{pausas}}
|
|
380
|
+
{{linha_variante}}
|
|
381
|
+
{{regra_de_pausa}}
|
|
382
|
+
|
|
383
|
+
CENTRAL RULE: the mode relaxes the pause, NEVER verification.
|
|
384
|
+
{{invariantes}}
|
|
385
|
+
|
|
386
|
+
## Thread context
|
|
387
|
+
- thread: {{thread}} (slug {{slug}})
|
|
388
|
+
- project: {{projeto_nome}} (abbrev {{projeto_abbrev}})
|
|
389
|
+
- stamped base: {{base_branch}} @ {{base_commit}}
|
|
390
|
+
- working directory: {{diretorio}}
|
|
391
|
+
- resumable work: {{trabalho}} (check and PR drafts, reviews and proof lists)
|
|
392
|
+
- thread state: .orkastery/threads/{{thread}}/thread.json
|
|
393
|
+
- ledger: .orkastery/threads/{{thread}}/ledger.jsonl
|
|
394
|
+
|
|
395
|
+
## Builder request
|
|
396
|
+
{{pedido}}
|
|
397
|
+
{{memoria_injetada}}
|
|
398
|
+
{{fecho_go}}
|
|
399
|
+
|
|
400
|
+
## Session isolation
|
|
401
|
+
|
|
402
|
+
The runtime may be the same for the conductor and reviewer. Independence requires distinct native IDs
|
|
403
|
+
and links proven by the core; a role name in the prompt is not authority. This session executes the
|
|
404
|
+
received block without opening recursion, approving a gate, or validating its own work. Preserve the
|
|
405
|
+
configured runtime/model/effort and \`interactive\`/\`worktree\` profile. Authentication failure remains
|
|
406
|
+
a blocker; do not change provider, sandbox, or identity.
|
|
407
|
+
|
|
408
|
+
## Evidence rules
|
|
409
|
+
{{regras_de_evidencia}}`;
|
|
341
410
|
/** Os templates que vem dentro do `ork`, por id. */
|
|
342
411
|
exports.TEMPLATES_EMBUTIDOS = {
|
|
343
412
|
'fase-padrao': exports.TEMPLATE_FASE_PADRAO,
|
|
413
|
+
'fase-padrao.en': exports.TEMPLATE_FASE_PADRAO_EN,
|
|
344
414
|
};
|
|
345
415
|
/**
|
|
346
416
|
* Carrega templates de um conjunto de embutidos, sobrescritos pelos `.md` de um diretorio.
|
|
@@ -382,50 +452,74 @@ function exigirTemplate(id, raiz) {
|
|
|
382
452
|
const achado = carregarTemplates(raiz).find((t) => t.id === id);
|
|
383
453
|
if (!achado) {
|
|
384
454
|
const ids = carregarTemplates(raiz).map((t) => t.id).join(', ');
|
|
385
|
-
throw new Error(
|
|
455
|
+
throw new Error((0, locale_1.msg)().prompts.cli.templateNaoExiste(id, ids));
|
|
386
456
|
}
|
|
387
457
|
return achado;
|
|
388
458
|
}
|
|
389
459
|
/**
|
|
390
460
|
* O template que conduz a fase: `fase-<minuscula>` quando o projeto versionou um so para ela,
|
|
391
461
|
* senao o `fase-padrao`. E o unico ponto de resolucao, para nao haver duas regras de escolha.
|
|
462
|
+
*
|
|
463
|
+
* RM-061 F3c: com o dono em ingles, o template do projeto vence o embutido e o da fase vence o padrao; no mesmo
|
|
464
|
+
* nivel, o `.en` vem antes. O projeto que versionou o proprio prompt nunca o perde porque o dono fala ingles: sem o
|
|
465
|
+
* par `.en`, a fase sai em pt-BR, e o `ork prompt lint` avisa (`avisosDeLingua`).
|
|
392
466
|
*/
|
|
393
|
-
function templateDaFase(fase, raiz) {
|
|
467
|
+
function templateDaFase(fase, raiz, locale = (0, locale_1.localeAtivo)()) {
|
|
394
468
|
const templates = carregarTemplates(raiz);
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
469
|
+
const achar = (id, soDoProjeto = false) => templates.find((t) => t.id === id && (!soDoProjeto || t.origem !== 'embutido'));
|
|
470
|
+
const especifico = `fase-${fase.toLowerCase()}`;
|
|
471
|
+
const candidatos = locale === 'en'
|
|
472
|
+
? [achar(`${especifico}.en`), achar(especifico), achar('fase-padrao.en', true), achar('fase-padrao', true), achar('fase-padrao.en')]
|
|
473
|
+
: [achar(especifico), achar('fase-padrao')];
|
|
474
|
+
const escolhido = candidatos.find((t) => t !== undefined);
|
|
475
|
+
if (!escolhido)
|
|
476
|
+
throw new Error((0, locale_1.msg)().prompts.cli.templatePadraoAusente);
|
|
477
|
+
return escolhido;
|
|
478
|
+
}
|
|
479
|
+
/** RM-061 F3c: a lingua de um template de fase, pelo sufixo do id; os valores do prompt falam a mesma. */
|
|
480
|
+
function idiomaDoTemplate(t) {
|
|
481
|
+
return t.id.endsWith('.en') ? 'en' : 'pt-BR';
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* RM-061 F3c: com o dono em ingles, o template de fase do projeto sem o par `.en` do projeto vale como esta, em
|
|
485
|
+
* pt-BR. O lint avisa, para a troca de lingua nunca ser silenciosa; em pt-BR nao ha o que avisar.
|
|
486
|
+
*/
|
|
487
|
+
function avisosDeLingua(templates, lingua) {
|
|
488
|
+
if (lingua !== 'en')
|
|
489
|
+
return [];
|
|
490
|
+
const doProjeto = new Set(templates.filter((t) => t.origem !== 'embutido').map((t) => t.id));
|
|
491
|
+
return templates
|
|
492
|
+
.filter((t) => t.origem !== 'embutido' && t.id.startsWith('fase-') && !t.id.endsWith('.en') && !doProjeto.has(`${t.id}.en`))
|
|
493
|
+
.map((t) => ({ template: t.id, regra: 'idioma', gravidade: 'aviso', detalhe: (0, locale_1.msg)().prompts.cli.semParIngles(t.id) }));
|
|
402
494
|
}
|
|
403
495
|
/** Texto de `ork prompt lint` para a saida do CLI. */
|
|
404
496
|
function textoDoLint(problemas, quantos) {
|
|
497
|
+
const m = (0, locale_1.msg)().prompts.cli;
|
|
405
498
|
const linhas = [];
|
|
406
499
|
const erros = problemas.filter((p) => p.gravidade === 'erro');
|
|
407
500
|
const avisos = problemas.filter((p) => p.gravidade === 'aviso');
|
|
408
501
|
for (const p of problemas) {
|
|
409
|
-
linhas.push(` [${p.gravidade}] ${p.template} :: ${p.regra}`);
|
|
502
|
+
linhas.push(` [${m.gravidades[p.gravidade]}] ${p.template} :: ${p.regra}`);
|
|
410
503
|
linhas.push(` ${p.detalhe}`);
|
|
411
504
|
}
|
|
412
505
|
if (problemas.length === 0) {
|
|
413
|
-
linhas.push(
|
|
506
|
+
linhas.push(m.semProblema(quantos));
|
|
414
507
|
}
|
|
415
508
|
linhas.push('');
|
|
416
|
-
linhas.push(
|
|
509
|
+
linhas.push(m.resumoLint(quantos, erros.length, avisos.length));
|
|
417
510
|
return linhas.join('\n');
|
|
418
511
|
}
|
|
419
512
|
/** Texto de `ork prompt list`. */
|
|
420
513
|
function tabelaDeTemplates(templates) {
|
|
421
|
-
const
|
|
514
|
+
const m = (0, locale_1.msg)().prompts.cli;
|
|
515
|
+
const linhas = [m.tituloLista, ''];
|
|
422
516
|
for (const t of templates) {
|
|
423
|
-
linhas.push(` ${t.id.padEnd(16)} v${t.versao}
|
|
424
|
-
linhas.push(` ${' '.repeat(16)}
|
|
517
|
+
linhas.push(` ${t.id.padEnd(16)} v${t.versao} ${m.origem(t.origem)}`);
|
|
518
|
+
linhas.push(` ${' '.repeat(16)} ${m.fases(t.fases.length > 0 ? t.fases.join(' ') : m.todas)}`);
|
|
425
519
|
linhas.push(` ${' '.repeat(16)} ${t.descricao}`);
|
|
426
520
|
}
|
|
427
521
|
linhas.push('');
|
|
428
|
-
linhas.push(
|
|
522
|
+
linhas.push(m.comoVersionar);
|
|
429
523
|
return linhas.join('\n');
|
|
430
524
|
}
|
|
431
525
|
/**
|
package/dist/prova-minima.js
CHANGED
|
@@ -56,6 +56,7 @@ const fs = __importStar(require("node:fs"));
|
|
|
56
56
|
const path = __importStar(require("node:path"));
|
|
57
57
|
const ledger_1 = require("./ledger");
|
|
58
58
|
const thread_1 = require("./thread");
|
|
59
|
+
const locale_1 = require("./locale");
|
|
59
60
|
/** Teto de comandos por claim num ciclo sem CHECK (degrau 2). */
|
|
60
61
|
exports.LIMITE_DE_COMANDOS_SEM_CHECK = 2;
|
|
61
62
|
/** O ciclo da thread nao tem CHECK: a prova e a minima, feita pela propria GO. */
|
|
@@ -87,13 +88,11 @@ function comandoDoTesteFocado(teste) {
|
|
|
87
88
|
*/
|
|
88
89
|
function validarProvaSemCheck(verificar, comandoDeTesteDoManifesto) {
|
|
89
90
|
if (verificar.length > exports.LIMITE_DE_COMANDOS_SEM_CHECK) {
|
|
90
|
-
throw new
|
|
91
|
-
`(recebidos ${verificar.length}); use o teste focado ou declare a ausencia com ork claims ausente`);
|
|
91
|
+
throw new locale_1.ErroDoCatalogo((m) => m.claims.custoDeComandos(exports.LIMITE_DE_COMANDOS_SEM_CHECK, verificar.length));
|
|
92
92
|
}
|
|
93
93
|
const suite = comandoDeTesteDoManifesto?.trim();
|
|
94
94
|
if (suite && verificar.some((c) => c.includes(suite))) {
|
|
95
|
-
throw new
|
|
96
|
-
'use o teste focado do arquivo que mudou');
|
|
95
|
+
throw new locale_1.ErroDoCatalogo((m) => m.claims.custoDaSuite(suite));
|
|
97
96
|
}
|
|
98
97
|
}
|
|
99
98
|
/** Degrau 3: grava no ledger da thread que estes caminhos ficaram sem prova, e por que. */
|
|
@@ -101,9 +100,9 @@ function registrarProvaAusente(raiz, threadId, ausencia) {
|
|
|
101
100
|
(0, thread_1.lerThread)(raiz, threadId); // a thread tem de existir
|
|
102
101
|
const motivo = ausencia.motivo.trim();
|
|
103
102
|
if (!motivo)
|
|
104
|
-
throw new
|
|
103
|
+
throw new locale_1.ErroDoCatalogo((m) => m.claims.ausenteSemMotivo);
|
|
105
104
|
if (ausencia.paths.length === 0)
|
|
106
|
-
throw new
|
|
105
|
+
throw new locale_1.ErroDoCatalogo((m) => m.claims.ausenteSemCaminhos);
|
|
107
106
|
(0, ledger_1.registrar)((0, thread_1.dirThread)(raiz, threadId), threadId, ledger_1.TIPOS_DE_EVENTO.provaAusente, {
|
|
108
107
|
paths: ausencia.paths,
|
|
109
108
|
motivo,
|
package/dist/pulse-cadencia.js
CHANGED
|
@@ -63,6 +63,7 @@ const fs = __importStar(require("node:fs"));
|
|
|
63
63
|
const path = __importStar(require("node:path"));
|
|
64
64
|
const horario_1 = require("./horario");
|
|
65
65
|
const estado_thread_1 = require("./estado-thread");
|
|
66
|
+
const locale_1 = require("./locale");
|
|
66
67
|
exports.CONTRATO_CADENCIA = 'ork.pulse-cadencia/v1';
|
|
67
68
|
const ARQUIVO_CADENCIA = 'pulse-cadencia.json';
|
|
68
69
|
const ARQUIVO_ULTIMO_RESUMO = 'pulse-ultimo-resumo.json';
|
|
@@ -100,10 +101,10 @@ function lerCadencia(raiz, estadoDir) {
|
|
|
100
101
|
/** Grava a tag do dono. `por` e quem mandou (o remetente autenticado do canal, ou o operador). */
|
|
101
102
|
function gravarCadencia(raiz, tag, origem, estadoDir) {
|
|
102
103
|
if (!Object.hasOwn(exports.CADENCIAS, tag))
|
|
103
|
-
throw new Error(
|
|
104
|
+
throw new Error((0, locale_1.msg)().operacao.pulseCadencia.desconhecidaInterna(tag));
|
|
104
105
|
const por = origem.por.trim();
|
|
105
106
|
if (!por)
|
|
106
|
-
throw new Error(
|
|
107
|
+
throw new Error((0, locale_1.msg)().operacao.pulseCadencia.trocaSemAutor);
|
|
107
108
|
const gravada = { contrato: exports.CONTRATO_CADENCIA, tag, por, canal: origem.canal, em: origem.em ?? new Date().toISOString() };
|
|
108
109
|
const dir = dirDoMonitor(raiz, estadoDir);
|
|
109
110
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -158,6 +159,6 @@ function janelaAberta(def, ultimoResumoEm, quando, fuso = (0, horario_1.fusoDoDo
|
|
|
158
159
|
}
|
|
159
160
|
/** A confirmacao que volta ao dono pelo mesmo canal, no fuso dele. */
|
|
160
161
|
function textoDaCadencia(def, quando) {
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
const m = (0, locale_1.msg)().operacao.pulseCadencia;
|
|
163
|
+
return m.texto(m.descricoes[def.tag] ?? def.descricao, def.tag, (0, horario_1.formatarDataHoraRotulada)(inicioDaProximaJanela(def, quando)));
|
|
163
164
|
}
|