@orkastery/cli 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/README.md +18 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
- package/adapters/claude-code/README.md +195 -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/autoridade.json +56 -0
- package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
- package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
- package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
- package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
- package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
- package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
- package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
- package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
- package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -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-mesa/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
- package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
- package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +121 -0
- package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
- package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
- package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
- package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
- package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
- package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
- package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
- package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
- package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
- package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
- package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
- package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
- package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
- 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/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
- package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
- package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
- package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
- package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
- package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
- package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
- package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
- package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
- 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 +3 -3
- package/adapters/openclaw/README.md +83 -10
- 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/docs-en/markdownlint-cli2.jsonc +22 -0
- package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
- package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
- package/assets/docs-en/produto/README.md +14 -0
- package/assets/docs-en/produto/_modelo-feature.md +62 -0
- package/assets/docs-en/roadmap/README.md +14 -0
- package/assets/docs-en/roadmap/_modelo-item.md +75 -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 +193 -15
- package/dist/adapters/codex-controller-worker.js +12 -5
- package/dist/adapters/codex-events.js +16 -4
- package/dist/adapters/codex.js +13 -2
- package/dist/agents-md.js +24 -15
- package/dist/atualizar-branch.js +245 -0
- package/dist/auditoria.js +13 -11
- package/dist/auditrun.js +68 -48
- package/dist/autorizacao-duravel.js +327 -0
- package/dist/board.js +98 -43
- package/dist/branch-de-estado.js +39 -9
- package/dist/busca-semantica.js +7 -5
- package/dist/catalogo.js +35 -1
- package/dist/changelog-reconciliacao.js +290 -0
- package/dist/check-agil.js +500 -0
- package/dist/check-modo.js +41 -0
- package/dist/check-paralelo.js +183 -0
- package/dist/ci.js +255 -46
- package/dist/ciclos.js +8 -6
- package/dist/claim-lint.js +12 -8
- package/dist/claims-conferir.js +350 -0
- package/dist/claims.js +13 -10
- package/dist/company-brain-client.js +45 -3
- package/dist/company-brain-journal.js +2 -1
- package/dist/company-brain-migration.js +47 -6
- package/dist/conducao-batida.js +759 -0
- package/dist/conducao-sentinela.js +405 -0
- package/dist/conducao-texto.js +12 -18
- package/dist/conducao.js +206 -59
- package/dist/conhecimento-consulta.js +270 -0
- package/dist/conhecimento.js +514 -0
- 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 +103 -82
- package/dist/doctor-forja.js +345 -0
- package/dist/doctor-pulse-cron.js +294 -27
- package/dist/doctor-rede.js +18 -17
- package/dist/doctor.js +278 -116
- package/dist/dsn-da-memoria.js +417 -0
- package/dist/entrega-por-mod.js +503 -0
- package/dist/entrega-pr.js +158 -57
- package/dist/escopo-escrita.js +10 -1
- package/dist/esgotamentos.js +13 -11
- package/dist/estado-thread.js +42 -17
- package/dist/evalrunner.js +35 -32
- package/dist/experiencia-instalacao.js +45 -25
- package/dist/fabrica-batida.js +323 -0
- package/dist/fabrica-estado.js +49 -16
- package/dist/fabrica-publicar.js +3 -1
- package/dist/fila-pesada.js +444 -0
- package/dist/fix.js +24 -21
- 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 +124 -81
- package/dist/gates.js +3 -28
- package/dist/handoff.js +33 -19
- 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 +53 -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 +72 -3
- package/dist/hitl-sessions.js +62 -9
- package/dist/hitl-tempo-parado.js +4 -4
- package/dist/hitl-texto-livre.js +7 -4
- package/dist/hitl.js +63 -64
- package/dist/horario.js +30 -7
- package/dist/hosts.js +155 -134
- package/dist/impedimento.js +108 -14
- package/dist/index.js +1421 -1019
- package/dist/indice-vetorial.js +14 -12
- package/dist/indice.js +7 -1
- package/dist/init.js +54 -49
- package/dist/instabilidade.js +144 -0
- package/dist/integracoes-locais.js +4 -0
- package/dist/intelligence-graph-cli.js +213 -88
- package/dist/intelligence-graph-contexto.js +56 -17
- package/dist/intelligence-graph-contract.js +2 -1
- package/dist/intelligence-graph-extract-md.js +56 -4
- package/dist/intelligence-graph-extract-ts.js +71 -3
- package/dist/intelligence-graph-query.js +96 -34
- package/dist/leases.js +19 -18
- package/dist/ledger-stats.js +17 -16
- package/dist/ledger.js +46 -2
- package/dist/licoes.js +12 -11
- package/dist/liveness.js +6 -3
- package/dist/locale-accounts.js +220 -0
- package/dist/locale-adapter.js +291 -0
- package/dist/locale-ajuda.js +833 -0
- package/dist/locale-audit.js +199 -0
- package/dist/locale-claims.js +213 -0
- package/dist/locale-conducao.js +138 -0
- package/dist/locale-conhecimento.js +181 -0
- package/dist/locale-decisao.js +205 -0
- package/dist/locale-docs.js +230 -0
- package/dist/locale-estado.js +101 -0
- package/dist/locale-forja.js +290 -0
- package/dist/locale-gerados.js +165 -0
- package/dist/locale-grafo.js +129 -0
- package/dist/locale-master.js +182 -0
- package/dist/locale-network.js +524 -0
- package/dist/locale-onboarding.js +92 -0
- package/dist/locale-operacao-restante.js +931 -0
- package/dist/locale-phase.js +151 -0
- package/dist/locale-projetos.js +100 -0
- package/dist/locale-prompts.js +194 -0
- package/dist/locale-pulse.js +349 -0
- package/dist/locale-reservas.js +87 -0
- package/dist/locale-retry.js +524 -0
- package/dist/locale-roadmap.js +102 -0
- package/dist/locale-security-scan.js +69 -0
- package/dist/locale-setup.js +192 -0
- package/dist/locale-ship.js +597 -0
- package/dist/locale-thread.js +421 -0
- package/dist/locale-verify.js +201 -0
- package/dist/locale-worktree.js +246 -0
- package/dist/locale.js +1258 -0
- package/dist/maestro-runtime.js +22 -3
- package/dist/manifest.js +415 -13
- package/dist/maquina-ociosa.js +211 -0
- package/dist/maquina.js +31 -7
- package/dist/master-digest.js +6 -1
- package/dist/master-nota-local.js +200 -0
- package/dist/master-nota.js +14 -8
- package/dist/master.js +139 -65
- package/dist/mcp-artifacts.js +11 -2
- package/dist/mcp-conhecimento.js +52 -0
- package/dist/mcp-experiencia.js +26 -5
- package/dist/mcp-git.js +23 -6
- package/dist/mcp-grafo.js +7 -4
- package/dist/mcp-install.js +73 -8
- package/dist/mcp-noctum.js +101 -0
- package/dist/mcp-server.js +90 -16
- package/dist/mcp-ship-transporte.js +977 -0
- package/dist/mcp-ship.js +71 -25
- package/dist/mcp-transportes.js +17 -0
- package/dist/mcp-verify.js +6 -1
- package/dist/memoria.js +63 -58
- package/dist/modos-migracao.js +8 -6
- package/dist/modos.js +20 -24
- package/dist/network-roadmap.js +90 -51
- package/dist/noctum-aceite.js +789 -0
- package/dist/noctum-arco.js +1418 -0
- package/dist/noctum-capacidade.js +141 -0
- package/dist/noctum-changelog.js +399 -0
- package/dist/noctum-cli.js +482 -0
- package/dist/noctum-coordenacao.js +1225 -0
- package/dist/noctum-entrega.js +1169 -0
- package/dist/noctum-envelope.js +1046 -0
- package/dist/noctum-execucao.js +376 -0
- package/dist/noctum-fechamento.js +405 -0
- package/dist/noctum-fila.js +314 -0
- package/dist/noctum-guarda.js +256 -0
- package/dist/noctum-integracao.js +507 -0
- package/dist/noctum-maquinas.js +383 -0
- package/dist/noctum-medicao.js +450 -0
- package/dist/noctum-modo.js +362 -0
- package/dist/noctum-pergunta-canal.js +96 -0
- package/dist/noctum-pergunta.js +115 -0
- package/dist/noctum-provas.js +838 -0
- package/dist/noctum-reconciliacao.js +591 -0
- package/dist/noctum-registro.js +215 -0
- package/dist/noctum-relatorio.js +827 -0
- package/dist/noctum-resposta.js +207 -0
- package/dist/noctum-sessoes-em-voo.js +93 -0
- package/dist/noctum-supervisao.js +649 -0
- package/dist/noctum-terminal.js +459 -0
- package/dist/noctum-transporte.js +655 -0
- package/dist/noctum-vigia.js +639 -0
- package/dist/ocupacao.js +32 -3
- package/dist/onboarding.js +56 -26
- package/dist/orkmind.js +48 -25
- package/dist/orquestracao.js +44 -47
- package/dist/parado-no-condutor.js +174 -127
- package/dist/phase.js +144 -63
- package/dist/policies.js +37 -4
- package/dist/portfolio.js +4 -2
- package/dist/postura-local.js +235 -0
- package/dist/preflight.js +11 -10
- package/dist/procedencia.js +220 -0
- package/dist/projeto-alvo.js +186 -24
- package/dist/prompts.js +140 -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 +151 -24
- package/dist/pulse-resposta.js +368 -4
- package/dist/pulse.js +188 -22
- package/dist/ratelimit.js +16 -6
- package/dist/recall.js +14 -13
- package/dist/redacao-saida.js +63 -0
- package/dist/rede-adesao.js +13 -8
- package/dist/rede-forja.js +108 -24
- package/dist/rede-status.js +66 -47
- package/dist/rede.js +86 -46
- package/dist/retomada-checkpoint.js +101 -0
- package/dist/retry.js +451 -212
- package/dist/roadmap-reservas.js +45 -28
- package/dist/roadmap-status.js +129 -33
- package/dist/runtime-ambiente.js +5 -0
- package/dist/runtime-context.js +284 -32
- package/dist/runtime-escada.js +423 -0
- package/dist/runtime-profiles.js +103 -46
- package/dist/runtimes.js +2 -1
- package/dist/saida-segura.js +3 -2
- package/dist/security-scan/agil.js +355 -0
- package/dist/security-scan/cli.js +76 -0
- package/dist/security-scan/compare.js +149 -0
- package/dist/security-scan/config.js +93 -0
- package/dist/security-scan/detect.js +97 -0
- package/dist/security-scan/executor.js +188 -0
- package/dist/security-scan/guard.js +180 -0
- package/dist/security-scan/imagem-de-lint.js +96 -0
- package/dist/security-scan/normalize/actionlint.js +12 -0
- package/dist/security-scan/normalize/eslint.js +12 -0
- package/dist/security-scan/normalize/gitleaks.js +13 -0
- package/dist/security-scan/normalize/golangci-lint.js +13 -0
- package/dist/security-scan/normalize/govulncheck.js +36 -0
- package/dist/security-scan/normalize/index.js +25 -0
- package/dist/security-scan/normalize/npm-audit.js +30 -0
- package/dist/security-scan/normalize/osv-scanner.js +32 -0
- package/dist/security-scan/normalize/oxlint.js +51 -0
- package/dist/security-scan/normalize/pip-audit.js +16 -0
- package/dist/security-scan/normalize/ruff.js +12 -0
- package/dist/security-scan/normalize/semgrep.js +20 -0
- package/dist/security-scan/normalize/trivy.js +33 -0
- package/dist/security-scan/normalize/util.js +204 -0
- package/dist/security-scan/normalize/zizmor.js +19 -0
- package/dist/security-scan/report.js +156 -0
- package/dist/security-scan/run.js +448 -0
- package/dist/security-scan/tools.js +62 -0
- package/dist/security-scan/trabalhador.js +74 -0
- package/dist/security-scan/types.js +15 -0
- package/dist/session-events.js +26 -5
- package/dist/session-watcher-claude.js +81 -20
- package/dist/session-watcher.js +340 -42
- package/dist/sessoes-contas.js +10 -1
- package/dist/sessoes-inventario.js +1 -1
- package/dist/sessoes.js +25 -23
- package/dist/setup.js +59 -58
- package/dist/ship-publicar.js +971 -0
- package/dist/ship.js +243 -97
- package/dist/steal.js +77 -0
- package/dist/superficie.js +14 -11
- package/dist/thread-close.js +12 -11
- package/dist/thread.js +274 -100
- 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 +13 -3
- package/dist/varredura-acoes.js +507 -0
- package/dist/verify.js +608 -76
- package/dist/vida-da-thread.js +254 -0
- package/dist/worktree-local.js +167 -0
- package/dist/worktree.js +99 -83
- package/dist/yaml.js +27 -8
- package/eval/casos/check-quality.json +77 -0
- package/eval/casos/security-auditor.json +148 -0
- package/eval/casos/security-remediation.json +161 -0
- package/eval/fixtures/security-scan/README.md +8 -0
- package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/go/Dockerfile +4 -0
- package/eval/fixtures/security-scan/go/README.md +4 -0
- package/eval/fixtures/security-scan/go/config.go +4 -0
- package/eval/fixtures/security-scan/go/go.mod +5 -0
- package/eval/fixtures/security-scan/go/go.sum +2 -0
- package/eval/fixtures/security-scan/go/main.go +31 -0
- package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/js/Dockerfile +3 -0
- package/eval/fixtures/security-scan/js/README.md +4 -0
- package/eval/fixtures/security-scan/js/package-lock.json +844 -0
- package/eval/fixtures/security-scan/js/package.json +10 -0
- package/eval/fixtures/security-scan/js/src/config.js +4 -0
- package/eval/fixtures/security-scan/js/src/server.js +17 -0
- package/eval/fixtures/security-scan/js/src/util.ts +4 -0
- package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
- package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
- package/eval/fixtures/security-scan/python/Dockerfile +3 -0
- package/eval/fixtures/security-scan/python/README.md +4 -0
- package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
- package/eval/fixtures/security-scan/python/app/config.py +2 -0
- package/eval/fixtures/security-scan/python/app/main.py +19 -0
- package/eval/fixtures/security-scan/python/requirements.txt +1 -0
- package/package.json +9 -4
- package/references/security-checklist.md +3 -3
- package/schemas/code-artifact-graph.v1.schema.json +2 -1
- package/skills/README.md +1 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/check-quality/SKILL.md +16 -0
- package/skills/phases/go-implementation/SKILL.md +6 -0
- package/skills/phases/security-remediation/SKILL.md +70 -0
- package/skills/reviewers/security-auditor/SKILL.md +25 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
// A pista de entrega (RM-059, fatia F7; ficha M7 do plano dos mods). Modulo puro: o argv da leitura do nucleo
|
|
2
|
+
// (`ork ship pista --json`, contrato `ork.ship-pista/v1`), a conferencia da saida campo a campo, a ordem das pistas, a
|
|
3
|
+
// linha da faixa, as linhas do painel com o que cada uma mostra ao dono e o desenho. Quem calcula as etapas e o
|
|
4
|
+
// proximo passo e o nucleo (D4 da thread ork-rm059pista); aqui so se le, se ordena e se desenha. O `$` fica no
|
|
5
|
+
// register.tsx, e o desenho recebe a tabela de elementos que a superficie resolveu.
|
|
6
|
+
import type { PistaAcao, PistaEstadoDaEtapa, PistaEtapa, PistaIdDaEtapa, PistaLinha, PistaMostrado, PistaPr, PistaProximo, PistaQuadro } from '../types'
|
|
7
|
+
|
|
8
|
+
export const ETAPAS: readonly PistaIdDaEtapa[] = ['check', 'verify', 'bundle', 'branch', 'pr', 'ci', 'conflito', 'entrega']
|
|
9
|
+
const ESTADOS: readonly PistaEstadoDaEtapa[] = ['feita', 'pendente', 'falhou', 'nao-lida', 'nao-se-aplica']
|
|
10
|
+
const ID_DE_THREAD = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,79}$/
|
|
11
|
+
const SHA = /^[0-9a-f]{40}$/
|
|
12
|
+
/** O nome curto de cada etapa no painel. */
|
|
13
|
+
export const NOME_DA_ETAPA: Readonly<Record<PistaIdDaEtapa, string>> = {
|
|
14
|
+
check: 'CHECK', verify: 'verify', bundle: 'bundle', branch: 'branch', pr: 'PR', ci: 'CI', conflito: 'conflito', entrega: 'entrega',
|
|
15
|
+
}
|
|
16
|
+
/** A marca de cada estado de etapa: o que falta e o que falhou saltam aos olhos. */
|
|
17
|
+
export const MARCA_DA_ETAPA: Readonly<Record<PistaEstadoDaEtapa, string>> = {
|
|
18
|
+
'feita': '✓', 'pendente': '·', 'falhou': '✗', 'nao-lida': '?', 'nao-se-aplica': '-',
|
|
19
|
+
}
|
|
20
|
+
/** Teto de pistas no quadro: cada uma ocupa umas cinco linhas do painel. */
|
|
21
|
+
export const TETO_DE_PISTAS = 30
|
|
22
|
+
const TETO_DE_TEXTO = 300
|
|
23
|
+
|
|
24
|
+
export type SaidaDoProcesso = { exitCode: number; stdout: string; stderr: string }
|
|
25
|
+
|
|
26
|
+
/** Uma linha so, sem caractere de controle, com teto: texto que vem do nucleo e vai para a tela. */
|
|
27
|
+
export function umaLinha(v: unknown, teto = TETO_DE_TEXTO): string {
|
|
28
|
+
const s = typeof v === 'string' ? v : v instanceof Error ? v.message : String(v)
|
|
29
|
+
return Array.from(s.replace(/\p{Cc}/gu, ' ').replace(/\s+/g, ' ').trim()).slice(0, teto).join('')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function exigirThread(thread: unknown): string {
|
|
33
|
+
if (typeof thread !== 'string' || !ID_DE_THREAD.test(thread)) throw new Error('ork-pista: id de thread invalido')
|
|
34
|
+
return thread
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** O argv da leitura da pista, de todas as threads ou de uma: o unico jeito de a Pista ler as etapas. */
|
|
38
|
+
export function argvDaPista(thread?: string): string[] {
|
|
39
|
+
return thread === undefined ? ['ork', 'ship', 'pista', '--json'] : ['ork', 'ship', 'pista', exigirThread(thread), '--json']
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A saida de um comando `--json` do nucleo, ou o motivo de nao ter sido lida (o CLI sem o subcomando incluso). */
|
|
43
|
+
export function jsonDaSaida(saida: SaidaDoProcesso, comando: string): unknown {
|
|
44
|
+
if (saida.exitCode === 2 && /(subcomando desconhecido|uso: ork ship|usage: ork ship|comando desconhecido)/i.test(`${saida.stderr}\n${saida.stdout}`)) {
|
|
45
|
+
throw new Error(`o ork deste PATH não tem ${comando}: atualize o CLI do Orkastery`)
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(saida.stdout)
|
|
49
|
+
} catch {
|
|
50
|
+
const motivo = umaLinha(saida.stderr || saida.stdout, 160) || `saída ${saida.exitCode}`
|
|
51
|
+
throw new Error(`${comando} não devolveu JSON (saída ${saida.exitCode}): ${motivo}`)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const texto = (v: unknown, teto = TETO_DE_TEXTO): string | null => (typeof v === 'string' && v.trim() !== '' ? umaLinha(v, teto) : null)
|
|
56
|
+
|
|
57
|
+
function etapaDe(bruto: unknown, id: PistaIdDaEtapa): PistaEtapa | null {
|
|
58
|
+
if (!bruto || typeof bruto !== 'object') return null
|
|
59
|
+
const e = bruto as Record<string, unknown>
|
|
60
|
+
if (e.id !== id || !ESTADOS.includes(e.estado as PistaEstadoDaEtapa)) return null
|
|
61
|
+
return { id, estado: e.estado as PistaEstadoDaEtapa, texto: texto(e.texto) ?? '' }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function prDe(bruto: unknown): PistaPr | null | undefined {
|
|
65
|
+
if (bruto === null) return null
|
|
66
|
+
if (!bruto || typeof bruto !== 'object') return undefined
|
|
67
|
+
const p = bruto as Record<string, unknown>
|
|
68
|
+
if (!Number.isSafeInteger(p.numero) || (p.numero as number) < 1 || !['aberto', 'mesclado', 'fechado'].includes(String(p.estado)) ||
|
|
69
|
+
typeof p.rascunho !== 'boolean' || typeof p.head !== 'string' || !SHA.test(p.head)) return undefined
|
|
70
|
+
const url = typeof p.url === 'string' && /^https:\/\/\S+$/.test(p.url) ? umaLinha(p.url, 300) : null
|
|
71
|
+
return { numero: p.numero as number, url, estado: p.estado as PistaPr['estado'], rascunho: p.rascunho, head: p.head }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function proximoDe(bruto: unknown): PistaProximo | null {
|
|
75
|
+
if (!bruto || typeof bruto !== 'object') return null
|
|
76
|
+
const p = bruto as Record<string, unknown>
|
|
77
|
+
const acao = p.acao === 'publicar' || p.acao === 'registrar' ? p.acao : p.acao === null ? null : undefined
|
|
78
|
+
if (acao === undefined || typeof p.disponivel !== 'boolean') return null
|
|
79
|
+
const t = texto(p.texto)
|
|
80
|
+
if (!t) return null
|
|
81
|
+
// So uma acao conhecida pode estar disponivel; o resto vira texto.
|
|
82
|
+
return { acao, disponivel: acao !== null && p.disponivel, texto: t, comando: texto(p.comando, 600) }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Uma pista do nucleo, conferida campo a campo; `null` quando ela nao tem a forma do contrato. */
|
|
86
|
+
export function linhaDaPista(bruto: unknown): PistaLinha | null {
|
|
87
|
+
if (!bruto || typeof bruto !== 'object') return null
|
|
88
|
+
const p = bruto as Record<string, unknown>
|
|
89
|
+
if (typeof p.thread !== 'string' || !ID_DE_THREAD.test(p.thread) || typeof p.publicavel !== 'boolean' || typeof p.conduzida !== 'boolean') return null
|
|
90
|
+
if (!Array.isArray(p.etapas) || p.etapas.length !== ETAPAS.length) return null
|
|
91
|
+
const etapas = ETAPAS.map((id, i) => etapaDe((p.etapas as unknown[])[i], id))
|
|
92
|
+
if (etapas.some(e => e === null)) return null
|
|
93
|
+
const pr = prDe(p.pr)
|
|
94
|
+
const proximo = proximoDe(p.proximo)
|
|
95
|
+
const head = typeof p.head === 'string' && SHA.test(p.head) ? p.head : null
|
|
96
|
+
if (pr === undefined || !proximo) return null
|
|
97
|
+
return {
|
|
98
|
+
thread: p.thread, nome: texto(p.nome, 120) ?? p.thread, tag: texto(p.tag, 20) ?? '', publicavel: p.publicavel, conduzida: p.conduzida,
|
|
99
|
+
branch: texto(p.branch, 200) ?? '', head, pr, etapas: etapas as PistaEtapa[], proximo,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* A saida do `ork ship pista --json`, conferida: o contrato, uma pista por thread (no maximo `TETO_DE_PISTAS`) e os
|
|
105
|
+
* avisos do que nao foi lido. Saida que nao e o contrato lanca, e o quadro anterior fica.
|
|
106
|
+
*/
|
|
107
|
+
export function lerPista(saida: SaidaDoProcesso, agora: number): PistaQuadro {
|
|
108
|
+
const bruto = jsonDaSaida(saida, 'ork ship pista') as Record<string, unknown> | null
|
|
109
|
+
if (!bruto || typeof bruto !== 'object' || bruto.contrato !== 'ork.ship-pista/v1' || !Array.isArray(bruto.pistas)) {
|
|
110
|
+
throw new Error('a saída do ork ship pista não é o contrato ork.ship-pista/v1')
|
|
111
|
+
}
|
|
112
|
+
const linhas = (bruto.pistas as unknown[]).map(linhaDaPista).filter((l): l is PistaLinha => l !== null)
|
|
113
|
+
const avisos: string[] = []
|
|
114
|
+
if (bruto.remotoLido === false) avisos.push(`o remoto ${texto(bruto.remoto, 60) ?? ''} não respondeu ao ls-remote`)
|
|
115
|
+
if (bruto.prsLidos === false) avisos.push(`os PRs não foram lidos: ${texto(bruto.prsNaoLidos, 200) ?? 'sem motivo'}`)
|
|
116
|
+
const descartadas = (bruto.pistas as unknown[]).length - linhas.length
|
|
117
|
+
if (descartadas > 0) avisos.push(`${descartadas} pista(s) fora do contrato ficaram de fora`)
|
|
118
|
+
if (linhas.length > TETO_DE_PISTAS) avisos.push(`${linhas.length - TETO_DE_PISTAS} pista(s) além do teto ficaram de fora`)
|
|
119
|
+
return { linhas: ordenarLinhas(linhas).slice(0, TETO_DE_PISTAS), lidoEm: agora, erro: null, avisos }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* A assinatura da secao `ship` do retrato do nucleo (o retrato da ponte): muda quando uma entrega anda (`ship_done`,
|
|
124
|
+
* `ship_started`, `ship_blocked`), e entao a pista e relida antes da idade. `null` quando o retrato nao veio.
|
|
125
|
+
*/
|
|
126
|
+
export function assinaturaDoRetrato(r: unknown): string | null {
|
|
127
|
+
const secao = (r as { retrato?: { sections?: { ship?: { items?: unknown } } } } | null)?.retrato?.sections?.ship
|
|
128
|
+
if (!secao || !Array.isArray(secao.items)) return null
|
|
129
|
+
return (secao.items as unknown[]).map(i => {
|
|
130
|
+
const x = (i ?? {}) as { id?: unknown; status?: unknown; facts?: { receiptAt?: unknown } }
|
|
131
|
+
return `${String(x.id)}|${String(x.status)}|${String(x.facts?.receiptAt ?? '')}`
|
|
132
|
+
}).sort().join(';')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** O ledger de thread que mudou (`classic.FileChanged`), pelo caminho; `null` para outro arquivo. */
|
|
136
|
+
export function threadDoLedger(caminho: unknown): string | null {
|
|
137
|
+
if (typeof caminho !== 'string') return null
|
|
138
|
+
const m = /\/\.orkastery\/threads\/([a-zA-Z0-9][a-zA-Z0-9._-]{0,79})\/ledger\.jsonl$/.exec(caminho)
|
|
139
|
+
return m ? m[1] as string : null
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** O peso de uma pista na ordem: o que tem botao, o que falhou, o que anda, o que ja foi entregue. */
|
|
143
|
+
export function pesoDaPista(l: PistaLinha): number {
|
|
144
|
+
if (l.proximo.disponivel) return 0
|
|
145
|
+
if (l.proximo.acao === 'publicar') return 1
|
|
146
|
+
if (l.etapas.some(e => e.estado === 'falhou')) return 2
|
|
147
|
+
if (l.etapas.find(e => e.id === 'entrega')?.estado === 'feita') return 4
|
|
148
|
+
return 3
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function ordenarLinhas(linhas: readonly PistaLinha[]): PistaLinha[] {
|
|
152
|
+
return [...linhas].sort((a, b) => pesoDaPista(a) - pesoDaPista(b) || a.thread.localeCompare(b.thread))
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** A marca da pista no painel: `!` com botao, `?` pede o dono, `x` falhou, `>` anda, `-` entregue. */
|
|
156
|
+
export function marcaDaPista(l: PistaLinha): string {
|
|
157
|
+
return ['!', '?', 'x', '>', '-'][pesoDaPista(l)] as string
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const plural = (n: number, um: string, varios: string) => `${n} ${n === 1 ? um : varios}`
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* A linha da faixa (D9): so o que pede o dono, sem repetir o que anda sozinho. Sem nada disso, a linha sai da
|
|
164
|
+
* faixa. A ponte ja escreve `pista: ` antes dela.
|
|
165
|
+
*/
|
|
166
|
+
export function textoDaFaixa(q: PistaQuadro): string | undefined {
|
|
167
|
+
const prontas = q.linhas.filter(l => l.proximo.acao === 'publicar' && l.proximo.disponivel).length
|
|
168
|
+
const doDono = q.linhas.filter(l => l.proximo.acao === 'publicar' && !l.proximo.disponivel).length
|
|
169
|
+
const registrar = q.linhas.filter(l => l.proximo.acao === 'registrar' && l.proximo.disponivel).length
|
|
170
|
+
const vermelhas = q.linhas.filter(l => l.etapas.some(e => (e.id === 'ci' || e.id === 'conflito') && e.estado === 'falhou')).length
|
|
171
|
+
const partes = [
|
|
172
|
+
prontas ? plural(prontas, 'pronta para publicar', 'prontas para publicar') : null,
|
|
173
|
+
doDono ? plural(doDono, 'pede o seu push', 'pedem o seu push') : null,
|
|
174
|
+
registrar ? plural(registrar, 'para registrar', 'para registrar') : null,
|
|
175
|
+
vermelhas ? plural(vermelhas, 'com CI vermelho ou conflito', 'com CI vermelho ou conflito') : null,
|
|
176
|
+
].filter((p): p is string => p !== null)
|
|
177
|
+
return partes.length ? `${partes.join(' · ')} · /pista` : undefined
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Quanto tempo faz, em palavras curtas. */
|
|
181
|
+
export function haQuanto(desde: number | null, agora: number): string {
|
|
182
|
+
if (desde === null) return 'ainda não lida'
|
|
183
|
+
const s = Math.max(0, Math.round((agora - desde) / 1000))
|
|
184
|
+
if (s < 60) return `lida há ${s} s`
|
|
185
|
+
const min = Math.round(s / 60)
|
|
186
|
+
return min < 60 ? `lida há ${min} min` : `lida há ${Math.round(min / 60)} h`
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Uma linha do painel, com o tipo que decide o elemento e o que ela mostra ao dono (para o registro da ponte). */
|
|
190
|
+
export type LinhaDoPainel = {
|
|
191
|
+
tipo: 'placar' | 'aviso' | 'vazio' | 'cabecalho' | 'etapas' | 'etapa' | 'proximo' | 'botao' | 'comando' | 'resultado'
|
|
192
|
+
texto: string
|
|
193
|
+
thread?: string
|
|
194
|
+
/** So na linha do botao: o comando do nucleo que ele chama (T7.3). */
|
|
195
|
+
acao?: 'publicar' | 'registrar'
|
|
196
|
+
mostrado?: PistaMostrado
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** O botao que o register.tsx decidiu para uma pista (o nucleo o declara disponivel), com o rotulo. */
|
|
200
|
+
export type BotaoDaPista = { acao: 'publicar' | 'registrar'; rotulo: string }
|
|
201
|
+
|
|
202
|
+
const linhaDasEtapas = (l: PistaLinha) => l.etapas.map(e => {
|
|
203
|
+
const nome = e.id === 'pr' && l.pr ? `PR #${l.pr.numero}` : NOME_DA_ETAPA[e.id]
|
|
204
|
+
return `${nome} ${MARCA_DA_ETAPA[e.estado]}`
|
|
205
|
+
}).join(' · ')
|
|
206
|
+
|
|
207
|
+
/** O texto do resultado do ultimo botao da thread, quando ha. */
|
|
208
|
+
export function textoDaAcao(a: PistaAcao | undefined): string | null {
|
|
209
|
+
if (!a) return null
|
|
210
|
+
const rotulo = a.acao === 'publicar' ? 'publicar' : 'registrar'
|
|
211
|
+
if (a.estado === 'rodando') return `${rotulo}: rodando no núcleo...`
|
|
212
|
+
return `${rotulo}: ${a.texto}`
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* As linhas do painel, na ordem do desenho. A pista em foco (`/pista <thread>`) vem primeiro. Cada pista: o
|
|
217
|
+
* cabecalho, as oito etapas numa linha, o texto de cada etapa que nao esta feita, o proximo passo do nucleo, o
|
|
218
|
+
* comando (para o dono, quando o modo pede o push dele) e o resultado do ultimo botao.
|
|
219
|
+
*/
|
|
220
|
+
export function linhasDoPainel(q: PistaQuadro, opcoes: { agora: number; foco?: string | null; acoes?: Readonly<Record<string, PistaAcao>>;
|
|
221
|
+
botoes?: Readonly<Record<string, BotaoDaPista>> }): LinhaDoPainel[] {
|
|
222
|
+
const saida: LinhaDoPainel[] = []
|
|
223
|
+
const prontas = q.linhas.filter(l => l.proximo.disponivel).length
|
|
224
|
+
saida.push({ tipo: 'placar', texto: `Pista de Entrega · ${plural(q.linhas.length, 'entrega', 'entregas')}` +
|
|
225
|
+
`${prontas ? ` · ${plural(prontas, 'com botão', 'com botão')}` : ''} · ${haQuanto(q.lidoEm, opcoes.agora)}` })
|
|
226
|
+
if (q.erro) saida.push({ tipo: 'aviso', texto: `a última leitura falhou: ${q.erro}` })
|
|
227
|
+
for (const aviso of q.avisos) saida.push({ tipo: 'aviso', texto: aviso })
|
|
228
|
+
if (!q.linhas.length) {
|
|
229
|
+
saida.push({ tipo: 'vazio', texto: q.lidoEm === null ? 'lendo a pista do núcleo...'
|
|
230
|
+
: 'Nenhuma entrega na pista: a thread entra aqui depois do CHECK, com a branch publicada ou com PR.' })
|
|
231
|
+
return saida
|
|
232
|
+
}
|
|
233
|
+
const foco = opcoes.foco ?? null
|
|
234
|
+
const ordem = foco ? [...q.linhas.filter(l => l.thread === foco), ...q.linhas.filter(l => l.thread !== foco)] : q.linhas
|
|
235
|
+
for (const l of ordem) {
|
|
236
|
+
const emFoco = l.thread === foco ? ' (em foco)' : ''
|
|
237
|
+
saida.push({ tipo: 'cabecalho', thread: l.thread, texto: `${marcaDaPista(l)} ${l.thread} ${l.tag} ${l.branch}${emFoco}` })
|
|
238
|
+
saida.push({ tipo: 'etapas', thread: l.thread, texto: ` ${linhaDasEtapas(l)}` })
|
|
239
|
+
for (const e of l.etapas.filter(x => x.estado === 'pendente' || x.estado === 'falhou' || x.estado === 'nao-lida')) {
|
|
240
|
+
saida.push({ tipo: 'etapa', thread: l.thread, texto: ` ${NOME_DA_ETAPA[e.id]}: ${e.texto}` })
|
|
241
|
+
}
|
|
242
|
+
const proximo = ` próximo: ${l.proximo.texto}`
|
|
243
|
+
saida.push({ tipo: 'proximo', thread: l.thread, texto: proximo,
|
|
244
|
+
mostrado: { chave: `pista:${l.thread}`, thread: l.thread, texto: `${l.thread}: ${l.proximo.texto}` } })
|
|
245
|
+
// O botao so aparece com a acao declarada e sem outro clique da mesma thread rodando no nucleo.
|
|
246
|
+
const botao = opcoes.botoes?.[l.thread]
|
|
247
|
+
if (botao && opcoes.acoes?.[l.thread]?.estado !== 'rodando') saida.push({ tipo: 'botao', thread: l.thread, acao: botao.acao, texto: botao.rotulo })
|
|
248
|
+
if (l.proximo.comando && !l.proximo.disponivel) {
|
|
249
|
+
const quem = l.proximo.acao === 'publicar' ? 'no seu terminal' : 'comando do núcleo'
|
|
250
|
+
saida.push({ tipo: 'comando', thread: l.thread, texto: ` ${quem}: ${l.proximo.comando}` })
|
|
251
|
+
}
|
|
252
|
+
const acao = textoDaAcao(opcoes.acoes?.[l.thread])
|
|
253
|
+
if (acao) saida.push({ tipo: 'resultado', thread: l.thread, texto: ` ${acao}`,
|
|
254
|
+
mostrado: { chave: `pista:${l.thread}:acao`, thread: l.thread, texto: `${l.thread}: ${acao}` } })
|
|
255
|
+
}
|
|
256
|
+
return saida
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* As linhas da tela que um texto com `wrap="wrap"` ocupa em `colunas` celulas: quebra por palavra, e a palavra maior que
|
|
261
|
+
* a linha quebra no meio. A `folga` (uma coluna, por padrao) tira colunas da conta: com ela a estimativa sobra.
|
|
262
|
+
*/
|
|
263
|
+
export function linhasDaTela(texto: string, colunas: number | undefined, folga = 1): number {
|
|
264
|
+
if (typeof colunas !== 'number' || !(colunas > folga)) return 1
|
|
265
|
+
const largura = colunas - folga
|
|
266
|
+
let linhas = 1
|
|
267
|
+
let usadas = 0
|
|
268
|
+
texto.split(' ').forEach((palavra, i) => {
|
|
269
|
+
let tamanho = Array.from(palavra).length
|
|
270
|
+
const espaco = i === 0 ? 0 : 1
|
|
271
|
+
if (usadas + espaco + tamanho <= largura) {
|
|
272
|
+
usadas += espaco + tamanho
|
|
273
|
+
return
|
|
274
|
+
}
|
|
275
|
+
if (usadas > 0) {
|
|
276
|
+
linhas++
|
|
277
|
+
usadas = 0
|
|
278
|
+
}
|
|
279
|
+
while (tamanho > largura) {
|
|
280
|
+
linhas++
|
|
281
|
+
tamanho -= largura
|
|
282
|
+
}
|
|
283
|
+
usadas = tamanho
|
|
284
|
+
})
|
|
285
|
+
return linhas
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* A altura de uma linha do painel na tela, sem e com a folga: `proximo` e `comando` quebram (`wrap="wrap"`); as outras
|
|
290
|
+
* truncam numa so.
|
|
291
|
+
*/
|
|
292
|
+
function alturasNaTela(l: { tipo?: string; texto?: string }, colunas: number | undefined): [number, number] {
|
|
293
|
+
if (l.tipo !== 'proximo' && l.tipo !== 'comando') return [1, 1]
|
|
294
|
+
return [linhasDaTela(l.texto ?? '', colunas, 0), linhasDaTela(l.texto ?? '', colunas, 1)]
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* O que esta inteiro dentro da janela de rolagem do painel: so isso conta como mostrado ao dono (M5). A janela conta
|
|
299
|
+
* linhas da tela (`offset` e `bodyRows`), e a linha que quebra nas `colunas` do corpo ocupa mais de uma. Como a quebra
|
|
300
|
+
* do motor e estimada, cada linha tem o topo mais cedo (a conta sem folga) e o mais tarde (com folga): ela so conta com
|
|
301
|
+
* o mais cedo abaixo do alto da janela e o fim mais tarde acima do pe dela, nas duas bordas.
|
|
302
|
+
*/
|
|
303
|
+
export function mostradosVisiveis(linhas: ReadonlyArray<{ tipo?: string; texto?: string; mostrado?: PistaMostrado }>,
|
|
304
|
+
janela: { offset: number; bodyRows: number } | undefined, colunas?: number): PistaMostrado[] {
|
|
305
|
+
if (!janela || !(janela.bodyRows > 0)) return []
|
|
306
|
+
const fim = janela.offset + janela.bodyRows
|
|
307
|
+
const vistos: PistaMostrado[] = []
|
|
308
|
+
let cedo = 0
|
|
309
|
+
let tarde = 0
|
|
310
|
+
for (const l of linhas) {
|
|
311
|
+
const [menor, maior] = alturasNaTela(l, colunas)
|
|
312
|
+
if (l.mostrado && cedo >= janela.offset && tarde + maior <= fim) vistos.push(l.mostrado)
|
|
313
|
+
cedo += menor
|
|
314
|
+
tarde += maior
|
|
315
|
+
}
|
|
316
|
+
return vistos
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/** Os gestos do painel: atualizar a pista e, na T7.3, os botoes que o nucleo declara. */
|
|
320
|
+
export type Gestos = {
|
|
321
|
+
atualizar?: () => void
|
|
322
|
+
publicar?: (thread: string) => void
|
|
323
|
+
registrar?: (thread: string) => void
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* A arvore do painel com os elementos que a superficie resolveu (no register.tsx), uma linha da
|
|
328
|
+
* tela por elemento: so `Box`, `Text` e `Button`, no terminal e no desktop.
|
|
329
|
+
*/
|
|
330
|
+
export function desenharPista(el: { Box: any; Text: any; Button: any }, q: PistaQuadro,
|
|
331
|
+
opcoes: { agora: number; foco?: string | null; acoes?: Readonly<Record<string, PistaAcao>>; botoes?: Readonly<Record<string, BotaoDaPista>> } & Gestos) {
|
|
332
|
+
const { Box, Text, Button } = el
|
|
333
|
+
return (
|
|
334
|
+
<Box flexDirection="column">
|
|
335
|
+
{linhasDoPainel(q, opcoes).map((l, i) => {
|
|
336
|
+
if (l.tipo === 'placar') {
|
|
337
|
+
return (
|
|
338
|
+
<Box key="placar" flexDirection="row">
|
|
339
|
+
<Text key="placar-texto" bold wrap="truncate">{l.texto}</Text>
|
|
340
|
+
<Button key="atualizar" label="Atualizar" onPress={() => opcoes.atualizar?.()} />
|
|
341
|
+
</Box>
|
|
342
|
+
)
|
|
343
|
+
}
|
|
344
|
+
if (l.tipo === 'cabecalho') return <Text key={`cabecalho:${l.thread}`} bold wrap="truncate">{l.texto}</Text>
|
|
345
|
+
if (l.tipo === 'botao' && l.thread && l.acao) {
|
|
346
|
+
const thread = l.thread
|
|
347
|
+
const apertar = l.acao === 'publicar' ? opcoes.publicar : opcoes.registrar
|
|
348
|
+
return <Button key={`${l.acao}:${thread}`} label={l.texto} onPress={() => apertar?.(thread)} />
|
|
349
|
+
}
|
|
350
|
+
if (l.tipo === 'comando') return <Text key={`comando:${l.thread}`} wrap="wrap">{l.texto}</Text>
|
|
351
|
+
if (l.tipo === 'proximo') return <Text key={`proximo:${l.thread}`} wrap="wrap">{l.texto}</Text>
|
|
352
|
+
return <Text key={`${l.tipo}:${l.thread ?? ''}:${i}`} dimColor wrap="truncate">{l.texto}</Text>
|
|
353
|
+
})}
|
|
354
|
+
</Box>
|
|
355
|
+
)
|
|
356
|
+
}
|