@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/thread.js
CHANGED
|
@@ -61,6 +61,9 @@ exports.avisoDaWorktree = avisoDaWorktree;
|
|
|
61
61
|
exports.prepararPedido = prepararPedido;
|
|
62
62
|
exports.pedidoDaThread = pedidoDaThread;
|
|
63
63
|
exports.novaThread = novaThread;
|
|
64
|
+
exports.dependenciasPendentes = dependenciasPendentes;
|
|
65
|
+
exports.prepararDependenciasPendentes = prepararDependenciasPendentes;
|
|
66
|
+
exports.prepararDependenciasDaThread = prepararDependenciasDaThread;
|
|
64
67
|
exports.exigirVarianteCompativel = exigirVarianteCompativel;
|
|
65
68
|
exports.blocoDaThread = blocoDaThread;
|
|
66
69
|
exports.pausaNaThread = pausaNaThread;
|
|
@@ -84,9 +87,12 @@ const ledger_1 = require("./ledger");
|
|
|
84
87
|
const estado_thread_1 = require("./estado-thread");
|
|
85
88
|
const creation_operation_store_1 = require("./creation-operation-store");
|
|
86
89
|
const horario_1 = require("./horario");
|
|
90
|
+
const check_modo_1 = require("./check-modo");
|
|
87
91
|
const maquina_1 = require("./maquina");
|
|
88
92
|
const conducao_texto_1 = require("./conducao-texto");
|
|
89
93
|
const locale_1 = require("./locale");
|
|
94
|
+
const branch_de_estado_1 = require("./branch-de-estado");
|
|
95
|
+
const dependencias_da_worktree_1 = require("./dependencias-da-worktree");
|
|
90
96
|
/** Diretorio de threads do projeto. */
|
|
91
97
|
function dirThreads(raiz) {
|
|
92
98
|
return path.join((0, manifest_1.dirEstado)((0, estado_thread_1.raizDoEstado)(raiz)), 'threads');
|
|
@@ -172,9 +178,11 @@ function alvoDaWorktree(carregado, id, slug, opcoes = {}) {
|
|
|
172
178
|
*/
|
|
173
179
|
function worktreePrevista(carregado, id, slug, opcoes = {}) {
|
|
174
180
|
const alvo = alvoDaWorktree(carregado, id, slug, opcoes);
|
|
181
|
+
const base = opcoes.base ?? carregado.manifesto.worktree.base_branch;
|
|
182
|
+
const remoto = (0, branch_de_estado_1.exigirRemoto)(carregado.manifesto.fabrica.remoto, 'worktree');
|
|
175
183
|
const refs = opcoes.branchExistente
|
|
176
184
|
? [opcoes.branchExistente]
|
|
177
|
-
: [
|
|
185
|
+
: [(0, branch_de_estado_1.refRemota)(remoto, base), base, 'HEAD'];
|
|
178
186
|
let commit = null;
|
|
179
187
|
for (const ref of refs) {
|
|
180
188
|
const r = (0, util_1.exec)('git', ['rev-parse', '--verify', ref], carregado.raiz);
|
|
@@ -189,6 +197,36 @@ function worktreePrevista(carregado, id, slug, opcoes = {}) {
|
|
|
189
197
|
: commit === null ? 'sem-commit' : branchJaExiste ? 'branch-existe' : null;
|
|
190
198
|
return { ...alvo, commit, falha };
|
|
191
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Resolve a base de uma worktree nova. Com remoto configurado e presente, a fonte e sempre
|
|
202
|
+
* `refs/remotes/<remoto>/<base>` atualizada por um fetch explicito; a branch local pode pertencer a
|
|
203
|
+
* outra worktree e ficar parada indefinidamente. Repositorio sem esse remoto preserva o caso local.
|
|
204
|
+
*/
|
|
205
|
+
function baseAtualDaWorktree(carregado, base) {
|
|
206
|
+
const { raiz, manifesto } = carregado;
|
|
207
|
+
const remoto = (0, branch_de_estado_1.exigirRemoto)(manifesto.fabrica.remoto, 'worktree');
|
|
208
|
+
const temRemoto = (0, util_1.exec)('git', ['remote', 'get-url', '--', remoto], raiz).ok;
|
|
209
|
+
let ref = base;
|
|
210
|
+
if (temRemoto) {
|
|
211
|
+
ref = (0, branch_de_estado_1.refRemota)(remoto, base);
|
|
212
|
+
const ambiente = { ...process.env, GIT_TERMINAL_PROMPT: '0',
|
|
213
|
+
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND ?? 'ssh -o BatchMode=yes' };
|
|
214
|
+
const fetch = (0, util_1.exec)('git', ['fetch', '-q', '--no-tags', '--', remoto,
|
|
215
|
+
`+refs/heads/${base}:${ref}`], raiz, 120000, ambiente);
|
|
216
|
+
if (!fetch.ok) {
|
|
217
|
+
const saida = (fetch.stderr || fetch.stdout).trim().split('\n').slice(-2).join(' | ');
|
|
218
|
+
throw new locale_1.ErroDoCatalogo((m) => m.worktree.baseRemotaFalhou(remoto, base, saida));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const resolvida = (0, util_1.exec)('git', ['rev-parse', '--verify', ref], raiz);
|
|
222
|
+
if (!resolvida.ok) {
|
|
223
|
+
// Repositorio local ainda sem a branch do manifesto conserva a recusa historica do
|
|
224
|
+
// `git worktree add ... HEAD`; com remoto presente, o fetch acima ja teria recusado.
|
|
225
|
+
const head = (0, util_1.exec)('git', ['rev-parse', '--verify', 'HEAD'], raiz);
|
|
226
|
+
return { ref: 'HEAD', commit: head.ok ? head.stdout.trim() : util_1.COMMIT_DESCONHECIDO };
|
|
227
|
+
}
|
|
228
|
+
return { ref, commit: resolvida.stdout.trim() };
|
|
229
|
+
}
|
|
192
230
|
/**
|
|
193
231
|
* Cria a worktree isolada da thread (paralelismo sem colisao entre threads).
|
|
194
232
|
*
|
|
@@ -202,31 +240,38 @@ function criarWorktree(carregado, id, slug, opcoes = {}) {
|
|
|
202
240
|
(0, worktree_local_1.exigirPastaDasWorktrees)(raiz, manifesto);
|
|
203
241
|
const { dir, branch } = alvoDaWorktree(carregado, id, slug, opcoes);
|
|
204
242
|
if (fs.existsSync(dir)) {
|
|
205
|
-
throw new
|
|
243
|
+
throw new locale_1.ErroDoCatalogo((m) => m.worktree.worktreeJaExisteEm(dir));
|
|
206
244
|
}
|
|
207
245
|
const base = opcoes.base ?? manifesto.worktree.base_branch;
|
|
208
|
-
const
|
|
209
|
-
|
|
246
|
+
const resolvida = opcoes.branchExistente
|
|
247
|
+
? (() => {
|
|
248
|
+
const r = (0, util_1.exec)('git', ['rev-parse', '--verify', opcoes.branchExistente], raiz);
|
|
249
|
+
if (!r.ok)
|
|
250
|
+
throw new locale_1.ErroDoCatalogo((m) => m.worktree.baseInexistente(opcoes.branchExistente));
|
|
251
|
+
return { ref: opcoes.branchExistente, commit: r.stdout.trim() };
|
|
252
|
+
})()
|
|
253
|
+
: baseAtualDaWorktree(carregado, base);
|
|
210
254
|
// Fatia 2 do ensaio da 0.5.0 (P3): a pasta das worktrees que o ork cria agora nasce fora do git.
|
|
211
255
|
const pastaDasWorktrees = path.dirname(dir);
|
|
212
256
|
const pastaNova = !fs.existsSync(pastaDasWorktrees);
|
|
213
257
|
// Branch nova (`-b`) no caso comum; branch que ja existe no ciclo `merge-branch`.
|
|
214
258
|
const argumentos = opcoes.branchExistente
|
|
215
259
|
? ['worktree', 'add', dir, opcoes.branchExistente]
|
|
216
|
-
: ['worktree', 'add', '-b', branch, dir, ref];
|
|
260
|
+
: ['worktree', 'add', '-b', branch, dir, resolvida.ref];
|
|
217
261
|
const r = (0, util_1.exec)('git', argumentos, raiz);
|
|
218
262
|
if (!r.ok) {
|
|
219
|
-
|
|
263
|
+
const saida = (r.stderr || r.stdout).trim();
|
|
264
|
+
throw new locale_1.ErroDoCatalogo((m) => m.worktree.worktreeAddFalhou(saida));
|
|
220
265
|
}
|
|
221
266
|
if (pastaNova)
|
|
222
267
|
(0, util_1.ignorarPastaNoGit)(pastaDasWorktrees, (0, estado_thread_1.raizDoEstado)(raiz));
|
|
223
268
|
const lista = (0, util_1.exec)('git', ['worktree', 'list', '--porcelain'], raiz);
|
|
224
269
|
const criada = lista.ok && lista.stdout.split('\n').some((l) => l.trim() === `worktree ${dir}`);
|
|
225
270
|
if (!criada) {
|
|
226
|
-
throw new
|
|
271
|
+
throw new locale_1.ErroDoCatalogo((m) => m.worktree.worktreeNaoApareceu(dir));
|
|
227
272
|
}
|
|
228
273
|
(0, estado_thread_1.vincularEstado)(raiz, id, dir);
|
|
229
|
-
return { dir, branch };
|
|
274
|
+
return { dir, branch, commit: resolvida.commit };
|
|
230
275
|
}
|
|
231
276
|
/**
|
|
232
277
|
* Resolve `--worktree`, `--sem-worktree` e `worktree.por_thread`. As flags vencem a chave; as duas juntas, ou
|
|
@@ -387,7 +432,63 @@ function gravarPedido(dir, texto) {
|
|
|
387
432
|
function novaThread(carregado, opcoes) {
|
|
388
433
|
if (opcoes.dryRun)
|
|
389
434
|
return criarThreadSerializada(carregado, opcoes);
|
|
390
|
-
|
|
435
|
+
const criada = (0, creation_operation_store_1.withCreationLock)((0, estado_thread_1.raizDoEstado)(carregado.raiz), 'threads', () => criarThreadSerializada(carregado, opcoes));
|
|
436
|
+
// RM-037 (defeito 2 de 19 e 20/10/2026): o preparo das dependencias roda depois da trava de criacao, que espera
|
|
437
|
+
// segundos, e nao os minutos de um `npm ci`.
|
|
438
|
+
if (!criada.gravada || !criada.worktreePor || !criada.thread.worktree)
|
|
439
|
+
return criada;
|
|
440
|
+
if (opcoes.adiarDependencias) {
|
|
441
|
+
adiarDependenciasDaThread(carregado, criada.thread.id, criada.thread.worktree);
|
|
442
|
+
return { ...criada, dependencias: null };
|
|
443
|
+
}
|
|
444
|
+
return { ...criada, dependencias: prepararDependenciasDaThread(carregado, criada.thread.id, criada.thread.worktree) };
|
|
445
|
+
}
|
|
446
|
+
/** RM-037 (CHECK 3 da ork-rm037defeit2): a criacao que nao pode esperar o preparo so o anota como pendente. */
|
|
447
|
+
function adiarDependenciasDaThread(carregado, id, dir) {
|
|
448
|
+
const { dependencias } = carregado.manifesto.worktree;
|
|
449
|
+
if (!dependencias)
|
|
450
|
+
return;
|
|
451
|
+
(0, ledger_1.registrar)(dirThread(carregado.raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeDependenciasPendentes, { dir, comando: dependencias, fonte: 'worktree.dependencias do manifesto' });
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* RM-037 (CHECK 3 da ork-rm037defeit2): a worktree `dir` tem o preparo adiado na criacao sem um preparo ok depois dele? O
|
|
455
|
+
* preparo que falhou nao cobre: a baseline e o verify o repetem e recusam seguir enquanto ele falhar.
|
|
456
|
+
*/
|
|
457
|
+
function dependenciasPendentes(eventos, dir) {
|
|
458
|
+
let pendente = false;
|
|
459
|
+
for (const e of eventos) {
|
|
460
|
+
if (typeof e.dir !== 'string' || path.resolve(e.dir) !== path.resolve(dir))
|
|
461
|
+
continue;
|
|
462
|
+
if (e.tipo === ledger_1.TIPOS_DE_EVENTO.worktreeDependenciasPendentes)
|
|
463
|
+
pendente = true;
|
|
464
|
+
else if (e.tipo === ledger_1.TIPOS_DE_EVENTO.worktreeDependencias && e.ok === true)
|
|
465
|
+
pendente = false;
|
|
466
|
+
}
|
|
467
|
+
return pendente;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* RM-037 (CHECK 3 da ork-rm037defeit2): roda o preparo que a criacao adiou, antes de a baseline ou o verify rodarem um
|
|
471
|
+
* comando, com a vez na fila pesada que eles ja seguram; `antes` so e chamado quando ha preparo a rodar (a renovacao da
|
|
472
|
+
* conducao pelo prazo dele), e o `executor` da operacao, quando ela traz um (o do sandbox do MCP), roda o preparo no lugar
|
|
473
|
+
* do executor do verify. Devolve o preparo rodado agora, ou `null` sem nada pendente; quem chama recusa a falha.
|
|
474
|
+
*/
|
|
475
|
+
function prepararDependenciasPendentes(carregado, id, dir, opcoes = {}) {
|
|
476
|
+
if (!dependenciasPendentes((0, ledger_1.lerLedger)(dirThread(carregado.raiz, id)), dir))
|
|
477
|
+
return null;
|
|
478
|
+
opcoes.antes?.();
|
|
479
|
+
return prepararDependenciasDaThread(carregado, id, dir, opcoes.executor);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* RM-037 (defeito 2 de 19 e 20/10/2026): roda `worktree.dependencias` na worktree que acabou de nascer e grava o
|
|
483
|
+
* resultado no ledger da thread. Sem a chave no manifesto, nada roda e nada se grava. A falha nao desfaz nada.
|
|
484
|
+
*/
|
|
485
|
+
function prepararDependenciasDaThread(carregado, id, dir, executor) {
|
|
486
|
+
const comando = carregado.manifesto.worktree.dependencias;
|
|
487
|
+
if (!comando)
|
|
488
|
+
return null;
|
|
489
|
+
const preparo = (0, dependencias_da_worktree_1.prepararDependencias)(dir, comando, undefined, executor);
|
|
490
|
+
(0, ledger_1.registrar)(dirThread(carregado.raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeDependencias, (0, dependencias_da_worktree_1.eventoDoPreparo)(dir, preparo));
|
|
491
|
+
return preparo;
|
|
391
492
|
}
|
|
392
493
|
/**
|
|
393
494
|
* I-42 (D12): variante que redesenha blocos nao cabe num modo de bloco unico e parcial.
|
|
@@ -552,10 +653,9 @@ function criarThreadSerializada(carregado, opcoes) {
|
|
|
552
653
|
branchExistente: opcoes.branch,
|
|
553
654
|
});
|
|
554
655
|
thread.worktree = worktreeCriada.dir;
|
|
555
|
-
const commitDaBranch = (0, util_1.exec)('git', ['rev-parse', worktreeCriada.branch], raiz);
|
|
556
656
|
thread.base = {
|
|
557
657
|
branch: worktreeCriada.branch,
|
|
558
|
-
commit:
|
|
658
|
+
commit: worktreeCriada.commit,
|
|
559
659
|
};
|
|
560
660
|
}
|
|
561
661
|
// RM-059 (T6.0): o pedido vai ao lado do thread.json, so com permissao do dono, como ele, e antes dele: o
|
|
@@ -652,6 +752,10 @@ function resumoDaThread(thread, conducao) {
|
|
|
652
752
|
if (thread.score) {
|
|
653
753
|
linhas.push(campo(r.score, m.score(thread.score.valor, thread.score.avaliadoPor, thread.score.regime, (0, horario_1.formatarDataHoraRotulada)(thread.score.avaliadoEm))));
|
|
654
754
|
}
|
|
755
|
+
// RM-072 (D17): o modo do ultimo CHECK, so quando a thread ja teve verify.
|
|
756
|
+
if (thread.check) {
|
|
757
|
+
linhas.push(campo(r.check, m.check(check_modo_1.NOME_DO_MODO[thread.check.modo], thread.check.origem, (0, horario_1.formatarDataHoraRotulada)(thread.check.em), (0, util_1.shaCurto)(thread.check.commit))));
|
|
758
|
+
}
|
|
655
759
|
linhas.push(m.blocosPrevistos);
|
|
656
760
|
for (const b of thread.blocos) {
|
|
657
761
|
const marca = b.pausa ? m.pausaPrevista(m.pausaSobre(b.pausaSobre)) : m.semPausa;
|
|
@@ -688,23 +792,22 @@ function threadsDaListagem(raiz, opcoes = {}) {
|
|
|
688
792
|
/** Tabela de `ork thread list`. */
|
|
689
793
|
function tabelaDeThreads(raiz, opcoes = {}) {
|
|
690
794
|
const linhas = threadsDaListagem(raiz, opcoes);
|
|
795
|
+
// RM-061 (F3b): o texto pelo catalogo; o status (dado do `--json`) so se traduz na impressao, pelo id.
|
|
796
|
+
const mt = (0, locale_1.msg)().thread;
|
|
691
797
|
if (linhas.length === 0) {
|
|
692
798
|
// A divida paga aqui: a mensagem sugeria `--modo default`, um modo que
|
|
693
799
|
// `parseModo` recusa, e e a origem provavel das 3 threads com `modo: default`
|
|
694
800
|
// gravadas em disco. A sugestao agora e um modo que existe.
|
|
695
|
-
|
|
696
|
-
? 'Nenhuma thread em .orkastery/threads.'
|
|
697
|
-
: 'Nenhuma thread aberta ou pausada (use --todas para ver as fechadas).';
|
|
698
|
-
return `${vazio} Crie uma com: ork thread new "<nome>" --modo ${modos_1.ORDEM_DOS_MODOS[0]}`;
|
|
801
|
+
return mt.listaVazia(opcoes.todas === true, modos_1.ORDEM_DOS_MODOS[0]);
|
|
699
802
|
}
|
|
700
803
|
const corpo = linhas.map((l) => [
|
|
701
|
-
l.id, l.slug, l.tag, l.fase, l.status, String(l.pausas), String(l.sessoes),
|
|
804
|
+
l.id, l.slug, l.tag, l.fase, mt.status(l.status), String(l.pausas), String(l.sessoes),
|
|
702
805
|
]);
|
|
703
|
-
const t = (0, util_1.tabela)([
|
|
806
|
+
const t = (0, util_1.tabela)([...mt.colunasDaLista], corpo);
|
|
704
807
|
if (opcoes.todas === true)
|
|
705
808
|
return t;
|
|
706
809
|
const fechadas = listarIds(raiz).length - linhas.length;
|
|
707
|
-
return fechadas > 0 ? `${t}\n\n
|
|
810
|
+
return fechadas > 0 ? `${t}\n\n${mt.fechadasOmitidas(fechadas)}` : t;
|
|
708
811
|
}
|
|
709
812
|
/** Fase valida e pertencente ao ciclo da thread. */
|
|
710
813
|
function exigirFase(thread, bruto) {
|
package/dist/tokens.js
CHANGED
|
@@ -63,6 +63,7 @@ const modos_1 = require("./modos");
|
|
|
63
63
|
const phase_1 = require("./phase");
|
|
64
64
|
const thread_1 = require("./thread");
|
|
65
65
|
const util_1 = require("./util");
|
|
66
|
+
const locale_1 = require("./locale");
|
|
66
67
|
/**
|
|
67
68
|
* Janela nominal usada na estimativa por transcript.
|
|
68
69
|
* Declarada, nao escondida: quem le a medida sabe contra o que ela foi calculada.
|
|
@@ -208,21 +209,24 @@ function gateDeTokens(carregado, threadId, opcoes = {}) {
|
|
|
208
209
|
}
|
|
209
210
|
/** Texto de `ork gate next`. */
|
|
210
211
|
function textoDoGateDeTokens(v) {
|
|
212
|
+
const m = (0, locale_1.msg)().operacao.restante.gate.tokens;
|
|
213
|
+
const detalhe = m.localizarDetalhe(v.medida.fonte, v.medida.detalhe);
|
|
214
|
+
const razao = m.localizarRazao(v.medida.ocupacao, v.limiares.rotate_above, v.limiares.force_rotate_above, v.passoPesado, v.razao.includes('refazer fase reprovada'), v.proximoPasso, v.razao);
|
|
211
215
|
const linhas = [];
|
|
212
|
-
linhas.push(
|
|
213
|
-
linhas.push(
|
|
214
|
-
linhas.push(
|
|
215
|
-
linhas.push(
|
|
216
|
-
linhas.push(
|
|
217
|
-
linhas.push(
|
|
216
|
+
linhas.push(m.titulo(v.thread));
|
|
217
|
+
linhas.push(m.ocupacao(v.medida.ocupacao === null ? m.naoMedivel : `${(v.medida.ocupacao * 100).toFixed(1)}%`));
|
|
218
|
+
linhas.push(m.fonte(v.medida.fonte));
|
|
219
|
+
linhas.push(m.detalhe(detalhe));
|
|
220
|
+
linhas.push(m.limiares(v.limiares.rotate_above, v.limiares.force_rotate_above));
|
|
221
|
+
linhas.push(m.proximo(v.proximoPasso, v.passoPesado ? m.pesado : m.leve));
|
|
218
222
|
linhas.push('');
|
|
219
|
-
linhas.push(
|
|
220
|
-
linhas.push(
|
|
223
|
+
linhas.push(m.veredito(v.veredito, v.decididoPor));
|
|
224
|
+
linhas.push(m.razao(razao));
|
|
221
225
|
if (v.slugSugerido) {
|
|
222
|
-
linhas.push(
|
|
223
|
-
linhas.push(
|
|
226
|
+
linhas.push(m.slug(v.slugSugerido));
|
|
227
|
+
linhas.push(m.handoff(v.thread, v.proximoPasso));
|
|
224
228
|
}
|
|
225
229
|
linhas.push('');
|
|
226
|
-
linhas.push(
|
|
230
|
+
linhas.push(m.ledger(v.thread));
|
|
227
231
|
return linhas.join('\n');
|
|
228
232
|
}
|
|
@@ -0,0 +1,297 @@
|
|
|
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.LIMITE_DE_ARQUIVOS_DO_TRABALHO = exports.LIMITE_TOTAL_DO_TRABALHO = exports.LIMITE_DE_ARQUIVO_DO_TRABALHO = void 0;
|
|
37
|
+
exports.diretorioDoTrabalho = diretorioDoTrabalho;
|
|
38
|
+
exports.caminhoDoTrabalho = caminhoDoTrabalho;
|
|
39
|
+
exports.garantirDiretorioDoTrabalho = garantirDiretorioDoTrabalho;
|
|
40
|
+
exports.gravarRespostaFinalDaSessao = gravarRespostaFinalDaSessao;
|
|
41
|
+
exports.resumirTrabalhoDaThread = resumirTrabalhoDaThread;
|
|
42
|
+
exports.formatarResumoDoTrabalho = formatarResumoDoTrabalho;
|
|
43
|
+
/** RM-064 T4: o trabalho pequeno da sessão acompanha a thread entre contas. */
|
|
44
|
+
const node_crypto_1 = require("node:crypto");
|
|
45
|
+
const fs = __importStar(require("node:fs"));
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const thread_1 = require("./thread");
|
|
48
|
+
exports.LIMITE_DE_ARQUIVO_DO_TRABALHO = 256 * 1024;
|
|
49
|
+
exports.LIMITE_TOTAL_DO_TRABALHO = 512 * 1024;
|
|
50
|
+
exports.LIMITE_DE_ARQUIVOS_DO_TRABALHO = 24;
|
|
51
|
+
const LIMITE_DE_ENTRADAS = 256;
|
|
52
|
+
const PROFUNDIDADE_MAXIMA = 4;
|
|
53
|
+
/** Caminho real no estado canônico. O prompt usa a forma relativa e portátil de `caminhoDoTrabalho`. */
|
|
54
|
+
function diretorioDoTrabalho(raiz, threadId) {
|
|
55
|
+
return path.join((0, thread_1.dirThread)(raiz, threadId), 'trabalho');
|
|
56
|
+
}
|
|
57
|
+
function caminhoDoTrabalho(threadId) {
|
|
58
|
+
return `.orkastery/threads/${threadId}/trabalho/`;
|
|
59
|
+
}
|
|
60
|
+
function abrirDiretorioDoTrabalho(raiz, threadId) {
|
|
61
|
+
const diretorio = diretorioDoTrabalho(raiz, threadId);
|
|
62
|
+
fs.mkdirSync(diretorio, { recursive: true, mode: 0o700 });
|
|
63
|
+
let fd;
|
|
64
|
+
try {
|
|
65
|
+
fd = fs.openSync(diretorio, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_DIRECTORY);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
throw new Error('trabalho da thread precisa ser diretorio real, nunca link');
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const aberto = fs.fstatSync(fd);
|
|
72
|
+
if (!aberto.isDirectory())
|
|
73
|
+
throw new Error('trabalho da thread precisa ser diretorio real, nunca link');
|
|
74
|
+
// `mode` de mkdir só vale na criação. Pelo descritor, uma troca de caminho não aplica modo em outro alvo.
|
|
75
|
+
fs.fchmodSync(fd, 0o700);
|
|
76
|
+
const real = fs.realpathSync(diretorio), peloCaminho = fs.statSync(real);
|
|
77
|
+
if (aberto.dev !== peloCaminho.dev || aberto.ino !== peloCaminho.ino)
|
|
78
|
+
throw new Error('trabalho da thread mudou durante a abertura');
|
|
79
|
+
return { diretorio, real, fd };
|
|
80
|
+
}
|
|
81
|
+
catch (erro) {
|
|
82
|
+
fs.closeSync(fd);
|
|
83
|
+
throw erro;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function garantirDiretorioDoTrabalho(raiz, threadId) {
|
|
87
|
+
const aberto = abrirDiretorioDoTrabalho(raiz, threadId);
|
|
88
|
+
fs.closeSync(aberto.fd);
|
|
89
|
+
const { diretorio } = aberto;
|
|
90
|
+
return diretorio;
|
|
91
|
+
}
|
|
92
|
+
function nomeSeguro(nome) {
|
|
93
|
+
return nome.replace(/[\u0000-\u001f\u007f]/g, '?');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Persiste a resposta do runtime na pasta privada da thread. O ledger recebe somente este recibo:
|
|
97
|
+
* conteúdo de agente pode conter detalhes grandes ou sensíveis e nunca é copiado para o evento.
|
|
98
|
+
*/
|
|
99
|
+
function gravarRespostaFinalDaSessao(raiz, threadId, sessionId, texto) {
|
|
100
|
+
if (!/^[a-zA-Z0-9-]{1,128}$/.test(sessionId))
|
|
101
|
+
throw new Error('id de sessão inválido para resposta final');
|
|
102
|
+
const aberto = abrirDiretorioDoTrabalho(raiz, threadId);
|
|
103
|
+
const bruto = Buffer.from(texto, 'utf8');
|
|
104
|
+
const truncada = bruto.byteLength > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO;
|
|
105
|
+
const conteudo = truncada
|
|
106
|
+
? Buffer.from(bruto.subarray(0, exports.LIMITE_DE_ARQUIVO_DO_TRABALHO).toString('utf8').replace(/\uFFFD$/, ''), 'utf8')
|
|
107
|
+
: bruto;
|
|
108
|
+
const arquivo = `resposta-final-${sessionId}.md`;
|
|
109
|
+
const alvo = path.join(aberto.diretorio, arquivo);
|
|
110
|
+
const temporario = path.join(aberto.diretorio, `.${arquivo}.${process.pid}.${(0, node_crypto_1.randomUUID)()}.tmp`);
|
|
111
|
+
try {
|
|
112
|
+
fs.writeFileSync(temporario, conteudo, { mode: 0o600, flag: 'wx' });
|
|
113
|
+
fs.chmodSync(temporario, 0o600);
|
|
114
|
+
try {
|
|
115
|
+
fs.linkSync(temporario, alvo);
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
if (e.code !== 'EEXIST')
|
|
119
|
+
throw e;
|
|
120
|
+
const existente = lerArquivoSeguro(aberto.real, alvo, {});
|
|
121
|
+
if (existente.estado !== 'ok' || !existente.conteudo.equals(conteudo))
|
|
122
|
+
throw new Error('resposta final já existe com conteúdo divergente');
|
|
123
|
+
}
|
|
124
|
+
const persistido = lerArquivoSeguro(aberto.real, alvo, {});
|
|
125
|
+
if (persistido.estado !== 'ok')
|
|
126
|
+
throw new Error('resposta final não pôde ser reconferida');
|
|
127
|
+
fs.chmodSync(alvo, 0o600);
|
|
128
|
+
return { arquivo, bytes: persistido.conteudo.byteLength,
|
|
129
|
+
sha256: (0, node_crypto_1.createHash)('sha256').update(persistido.conteudo).digest('hex'), truncada };
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
try {
|
|
133
|
+
fs.rmSync(temporario, { force: true });
|
|
134
|
+
}
|
|
135
|
+
catch { /* temporário já ausente */ }
|
|
136
|
+
fs.closeSync(aberto.fd);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const contido = (base, alvo) => alvo === base || alvo.startsWith(base + path.sep);
|
|
140
|
+
/** Abre a entrada sem seguir o componente final e nunca lê mais que o teto mais um byte. */
|
|
141
|
+
function lerArquivoSeguro(baseReal, absoluto, opcoes) {
|
|
142
|
+
try {
|
|
143
|
+
const antes = fs.realpathSync(absoluto);
|
|
144
|
+
if (!contido(baseReal, antes))
|
|
145
|
+
return { estado: 'link' };
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return { estado: 'outro' };
|
|
149
|
+
}
|
|
150
|
+
opcoes.antesDeAbrir?.(absoluto);
|
|
151
|
+
let fd;
|
|
152
|
+
try {
|
|
153
|
+
fd = fs.openSync(absoluto, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
|
|
154
|
+
}
|
|
155
|
+
catch (erro) {
|
|
156
|
+
return { estado: erro.code === 'ELOOP' ? 'link' : 'outro' };
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
const inicial = fs.fstatSync(fd);
|
|
160
|
+
if (!inicial.isFile())
|
|
161
|
+
return { estado: 'outro' };
|
|
162
|
+
if (inicial.size > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO)
|
|
163
|
+
return { estado: 'grande' };
|
|
164
|
+
const buffer = Buffer.alloc(exports.LIMITE_DE_ARQUIVO_DO_TRABALHO + 1);
|
|
165
|
+
let lidos = 0;
|
|
166
|
+
while (lidos < buffer.length) {
|
|
167
|
+
const n = fs.readSync(fd, buffer, lidos, buffer.length - lidos, null);
|
|
168
|
+
if (n === 0)
|
|
169
|
+
break;
|
|
170
|
+
lidos += n;
|
|
171
|
+
}
|
|
172
|
+
const final = fs.fstatSync(fd);
|
|
173
|
+
if (lidos > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO || final.size > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO)
|
|
174
|
+
return { estado: 'grande' };
|
|
175
|
+
// Confere que o caminho ainda aponta para o mesmo inode aberto e continua dentro da pasta.
|
|
176
|
+
let peloCaminho, realDepois;
|
|
177
|
+
try {
|
|
178
|
+
realDepois = fs.realpathSync(absoluto);
|
|
179
|
+
peloCaminho = fs.statSync(realDepois);
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return { estado: 'outro' };
|
|
183
|
+
}
|
|
184
|
+
if (!contido(baseReal, realDepois) || peloCaminho.dev !== final.dev || peloCaminho.ino !== final.ino)
|
|
185
|
+
return { estado: 'link' };
|
|
186
|
+
// Mudança durante a leitura não produz hash de estado híbrido.
|
|
187
|
+
if (lidos !== final.size || inicial.size !== final.size || inicial.mtimeMs !== final.mtimeMs || inicial.ctimeMs !== final.ctimeMs)
|
|
188
|
+
return { estado: 'outro' };
|
|
189
|
+
return { estado: 'ok', conteudo: buffer.subarray(0, lidos) };
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
fs.closeSync(fd);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Inventário deliberadamente limitado: não segue links, lê cada arquivo por descritor limitado e não deixa uma árvore
|
|
197
|
+
* de job dominar o prompt. A sessão sucessora recebe nomes, tamanhos e hashes; lê o arquivo pelo caminho se precisar.
|
|
198
|
+
*/
|
|
199
|
+
function resumirTrabalhoDaThread(raiz, threadId, opcoes = {}) {
|
|
200
|
+
const aberto = abrirDiretorioDoTrabalho(raiz, threadId);
|
|
201
|
+
const base = aberto.diretorio, baseReal = aberto.real;
|
|
202
|
+
const arquivos = [];
|
|
203
|
+
const ignorados = { grandes: 0, links: 0, excedentes: 0, outros: 0 };
|
|
204
|
+
let bytes = 0;
|
|
205
|
+
let entradas = 0;
|
|
206
|
+
const visitar = (diretorio, relativo, profundidade) => {
|
|
207
|
+
if (profundidade > PROFUNDIDADE_MAXIMA || entradas >= LIMITE_DE_ENTRADAS) {
|
|
208
|
+
ignorados.excedentes += 1;
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
let dir;
|
|
212
|
+
try {
|
|
213
|
+
const real = fs.realpathSync(diretorio);
|
|
214
|
+
if (!contido(baseReal, real) || !fs.lstatSync(diretorio).isDirectory()) {
|
|
215
|
+
ignorados.links += 1;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
dir = fs.opendirSync(diretorio);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
ignorados.outros += 1;
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const itens = [];
|
|
225
|
+
try {
|
|
226
|
+
while (entradas + itens.length < LIMITE_DE_ENTRADAS) {
|
|
227
|
+
const item = dir.readSync();
|
|
228
|
+
if (!item)
|
|
229
|
+
break;
|
|
230
|
+
itens.push(item);
|
|
231
|
+
}
|
|
232
|
+
if (entradas + itens.length >= LIMITE_DE_ENTRADAS && dir.readSync())
|
|
233
|
+
ignorados.excedentes += 1;
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
dir.closeSync();
|
|
237
|
+
}
|
|
238
|
+
entradas += itens.length;
|
|
239
|
+
itens.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
240
|
+
for (const item of itens) {
|
|
241
|
+
const absoluto = path.join(diretorio, item.name);
|
|
242
|
+
const nome = path.posix.join(relativo, nomeSeguro(item.name));
|
|
243
|
+
if (item.isSymbolicLink()) {
|
|
244
|
+
ignorados.links += 1;
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (item.isDirectory()) {
|
|
248
|
+
visitar(absoluto, nome, profundidade + 1);
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (!item.isFile()) {
|
|
252
|
+
ignorados.outros += 1;
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
// Lista ou orçamento já cheios: o arquivo só conta como excedente, sem ser aberto nem lido.
|
|
256
|
+
if (arquivos.length >= exports.LIMITE_DE_ARQUIVOS_DO_TRABALHO || bytes >= exports.LIMITE_TOTAL_DO_TRABALHO) {
|
|
257
|
+
ignorados.excedentes += 1;
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
const leitura = lerArquivoSeguro(baseReal, absoluto, opcoes);
|
|
261
|
+
if (leitura.estado !== 'ok') {
|
|
262
|
+
if (leitura.estado === 'grande')
|
|
263
|
+
ignorados.grandes += 1;
|
|
264
|
+
else if (leitura.estado === 'link')
|
|
265
|
+
ignorados.links += 1;
|
|
266
|
+
else
|
|
267
|
+
ignorados.outros += 1;
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
if (arquivos.length >= exports.LIMITE_DE_ARQUIVOS_DO_TRABALHO || bytes + leitura.conteudo.byteLength > exports.LIMITE_TOTAL_DO_TRABALHO) {
|
|
271
|
+
ignorados.excedentes += 1;
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
arquivos.push({ arquivo: nome, bytes: leitura.conteudo.byteLength,
|
|
275
|
+
sha256: (0, node_crypto_1.createHash)('sha256').update(leitura.conteudo).digest('hex') });
|
|
276
|
+
bytes += leitura.conteudo.byteLength;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
try {
|
|
280
|
+
visitar(base, '', 0);
|
|
281
|
+
return { caminho: caminhoDoTrabalho(threadId), arquivos, ignorados };
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
fs.closeSync(aberto.fd);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function formatarResumoDoTrabalho(resumo) {
|
|
288
|
+
const linhas = resumo.arquivos.length
|
|
289
|
+
? resumo.arquivos.map((a) => ` - \`${a.arquivo.replace(/`/g, '\\`')}\` (${a.bytes} bytes, sha256 \`${a.sha256}\`)`)
|
|
290
|
+
: [' - (nenhum arquivo pequeno)'];
|
|
291
|
+
const totalIgnorado = Object.values(resumo.ignorados).reduce((soma, n) => soma + n, 0);
|
|
292
|
+
if (totalIgnorado > 0) {
|
|
293
|
+
linhas.push(` - Ignorados pelos limites: ${resumo.ignorados.grandes} grandes, ${resumo.ignorados.links} links, ` +
|
|
294
|
+
`${resumo.ignorados.excedentes} excedentes, ${resumo.ignorados.outros} outros.`);
|
|
295
|
+
}
|
|
296
|
+
return linhas.join('\n');
|
|
297
|
+
}
|