@orkastery/cli 0.5.1 → 0.5.6
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/claude-code/README.md +158 -0
- package/adapters/claude-code/agents/ork-master.md +2 -0
- package/adapters/claude-code/commands/master.md +8 -0
- package/adapters/claude-code/commands/ork.md +9 -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-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 +117 -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-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 +18 -3
- package/adapters/hermes/README.md +1 -0
- package/adapters/hermes/bin/ork-network-status.sh +10 -0
- package/adapters/hermes/hermes.plugin.json +1 -0
- package/adapters/hermes/hitl-ingress/__init__.py +2 -2
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +7 -6
- package/adapters/openclaw/README.md +26 -5
- package/adapters/openclaw/dist/hitl-ingress.js +2 -2
- package/adapters/openclaw/dist/index.js +46 -11
- package/adapters/openclaw/openclaw.plugin.json +5 -1
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +2 -2
- package/adapters/openclaw/src/index.ts +49 -11
- 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/orkmind_bridge.py +117 -9
- package/dist/adapters/claude-bg.js +116 -18
- package/dist/adapters/codex.js +14 -4
- package/dist/agents-md.js +24 -14
- package/dist/auditrun.js +22 -3
- package/dist/board.js +20 -17
- package/dist/branch-de-estado.js +88 -10
- package/dist/busca-semantica.js +52 -12
- package/dist/canarios-rm057.js +149 -0
- package/dist/canarios.js +2 -0
- package/dist/catalogo.js +33 -0
- package/dist/ci.js +21 -8
- package/dist/claims-conferir.js +342 -0
- package/dist/claims.js +41 -1
- package/dist/company-brain-client.js +36 -1
- package/dist/company-brain-context.js +158 -22
- package/dist/company-brain-journal.js +2 -1
- package/dist/company-brain-migration.js +36 -1
- package/dist/conducao-sentinela.js +388 -0
- package/dist/conducao-texto.js +12 -18
- package/dist/conducao.js +122 -30
- package/dist/conhecimento.js +490 -0
- package/dist/docs.js +70 -17
- package/dist/doctor-pulse-cron.js +349 -0
- package/dist/doctor-rede.js +150 -0
- package/dist/doctor.js +195 -111
- package/dist/entrega-pr.js +42 -29
- package/dist/escopo-escrita.js +10 -1
- package/dist/esgotamentos.js +181 -0
- package/dist/estado-thread.js +23 -1
- package/dist/experiencia-instalacao.js +45 -25
- package/dist/experiencia.js +12 -2
- package/dist/fabrica-batida.js +310 -0
- package/dist/fabrica-estado.js +52 -14
- package/dist/fabrica-publicar.js +9 -1
- package/dist/fechamento.js +20 -66
- package/dist/fila-pesada.js +444 -0
- package/dist/fix.js +3 -2
- package/dist/forja.js +31 -7
- package/dist/gates.js +3 -24
- package/dist/handoff.js +10 -6
- package/dist/hitl-contract.js +59 -4
- package/dist/hitl-curto.js +11 -6
- package/dist/hitl-gates.js +5 -0
- package/dist/hitl-local-receipt.js +2 -0
- package/dist/hitl-lote.js +5 -2
- package/dist/hitl-resumo.js +38 -3
- package/dist/hitl-tempo-parado.js +201 -0
- package/dist/hitl-texto-livre.js +5 -5
- package/dist/hitl.js +29 -33
- package/dist/horario.js +41 -7
- package/dist/hosts.js +104 -11
- package/dist/impedimento.js +299 -0
- package/dist/index.js +961 -542
- package/dist/indice-vetorial.js +87 -10
- package/dist/indice.js +9 -1
- package/dist/init.js +56 -43
- package/dist/instabilidade.js +144 -0
- package/dist/integracoes-locais.js +4 -0
- package/dist/intelligence-graph-cli.js +170 -16
- package/dist/intelligence-graph-contexto.js +254 -0
- 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-parsers.js +6 -4
- package/dist/intelligence-graph-query.js +66 -19
- package/dist/leases.js +664 -87
- package/dist/ledger-stats.js +15 -1
- package/dist/ledger.js +18 -1
- package/dist/licoes.js +1 -0
- package/dist/liveness.js +6 -3
- package/dist/locale-ajuda.js +761 -0
- package/dist/locale-gerados.js +160 -0
- package/dist/locale-master.js +99 -0
- package/dist/locale-onboarding.js +92 -0
- package/dist/locale-phase.js +151 -0
- package/dist/locale-pulse.js +211 -0
- package/dist/locale-retry.js +385 -0
- package/dist/locale-roadmap.js +102 -0
- package/dist/locale-ship.js +494 -0
- package/dist/locale-thread.js +277 -0
- package/dist/locale-verify.js +125 -0
- package/dist/locale.js +714 -0
- package/dist/maestro-runtime.js +4 -1
- package/dist/manifest.js +149 -4
- package/dist/maquina.js +23 -4
- package/dist/master-digest.js +6 -1
- package/dist/master-nota.js +18 -11
- package/dist/master.js +145 -31
- package/dist/mcp-artifacts.js +43 -3
- package/dist/mcp-git.js +42 -8
- package/dist/mcp-grafo-worker.js +5 -3
- package/dist/mcp-grafo.js +55 -6
- package/dist/mcp-server.js +22 -3
- package/dist/mcp-ship.js +3 -1
- package/dist/mcp-verify.js +6 -1
- package/dist/memoria.js +48 -6
- package/dist/modos.js +3 -6
- package/dist/network-roadmap.js +196 -18
- package/dist/noctum-arco.js +911 -0
- package/dist/noctum-capacidade.js +141 -0
- package/dist/noctum-envelope.js +810 -0
- package/dist/noctum-execucao.js +304 -0
- package/dist/noctum-fila.js +280 -0
- package/dist/ocupacao.js +40 -5
- package/dist/onboarding.js +40 -21
- package/dist/orkmind.js +99 -7
- package/dist/orquestracao.js +24 -21
- package/dist/parado-no-condutor.js +219 -38
- package/dist/phase.js +160 -52
- package/dist/policies.js +56 -5
- package/dist/portfolio.js +8 -3
- package/dist/postura-local.js +234 -0
- package/dist/preflight.js +11 -10
- package/dist/procedencia.js +225 -0
- package/dist/projeto-alvo.js +132 -5
- package/dist/prompts.js +40 -1
- package/dist/prova-ativacao.js +75 -6
- package/dist/pulse-delivery.js +47 -4
- package/dist/pulse.js +98 -19
- package/dist/ratelimit.js +24 -6
- package/dist/recall.js +3 -1
- package/dist/redacao-saida.js +63 -0
- package/dist/rede-adesao.js +399 -0
- package/dist/rede-forja.js +289 -0
- package/dist/rede-projetos.js +239 -0
- package/dist/rede-status.js +337 -0
- package/dist/rede.js +980 -0
- package/dist/retry.js +291 -140
- package/dist/roadmap-reservas.js +20 -3
- package/dist/roadmap-status.js +150 -34
- package/dist/runtime-context.js +181 -3
- package/dist/runtime-profiles.js +22 -1
- package/dist/runtimes.js +2 -1
- package/dist/saida-segura.js +58 -0
- package/dist/session-events.js +7 -3
- package/dist/session-watcher-claude.js +120 -24
- package/dist/session-watcher.js +185 -33
- package/dist/sessoes-contas.js +187 -0
- package/dist/sessoes-inventario.js +6 -18
- package/dist/sessoes.js +83 -2
- package/dist/ship-publicar.js +800 -0
- package/dist/ship.js +157 -88
- package/dist/steal.js +77 -0
- package/dist/thread-close.js +3 -2
- package/dist/thread.js +299 -49
- package/dist/util.js +8 -1
- package/dist/verify.js +141 -52
- package/dist/vida-da-thread.js +254 -0
- package/dist/worktree-local.js +165 -0
- package/dist/worktree.js +25 -2
- package/dist/yaml.js +27 -8
- package/eval/fixtures/fx-pedido-colado/caso.json +20 -0
- package/package.json +7 -3
- package/references/definition-of-done.md +1 -1
- package/schemas/code-artifact-graph.v1.schema.json +2 -1
- package/skills/README.md +1 -1
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/master-metrics/SKILL.md +8 -3
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fatosDeCapacidade = fatosDeCapacidade;
|
|
4
|
+
exports.admitir = admitir;
|
|
5
|
+
exports.escolherConta = escolherConta;
|
|
6
|
+
const conducao_1 = require("./conducao");
|
|
7
|
+
const ledger_1 = require("./ledger");
|
|
8
|
+
const ocupacao_1 = require("./ocupacao");
|
|
9
|
+
const sessoes_contas_1 = require("./sessoes-contas");
|
|
10
|
+
const thread_1 = require("./thread");
|
|
11
|
+
const TERMINAIS = ['done', 'completed', 'exited', 'stopped', 'failed'];
|
|
12
|
+
/** O runtime mostra a sessão trabalhando agora: o claude-bg diz `running` ou `busy` (o watcher chama de `working`). */
|
|
13
|
+
const TRABALHANDO = ['running', 'busy', 'working'];
|
|
14
|
+
const estadoDe = (s) => String(s.state ?? s.status ?? '').trim().toLowerCase();
|
|
15
|
+
/**
|
|
16
|
+
* O runtime prova que a sessão do lease acabou? Presente com estado terminal ou fantasma, sim. Ausente, só no
|
|
17
|
+
* claude-bg (o `claude agents` lista as sessões que o daemon da conta mantém), com todas as fontes lidas e a conta
|
|
18
|
+
* dela entre as consultadas. O codex lista só rollouts recentes: ausência lá não prova nada.
|
|
19
|
+
*/
|
|
20
|
+
function encerradaPeloRuntime(dono, leitura, porSessao, semLacuna) {
|
|
21
|
+
const vista = porSessao.get(dono.sessionId);
|
|
22
|
+
if (vista)
|
|
23
|
+
return vista.fantasma || TERMINAIS.includes(estadoDe(vista));
|
|
24
|
+
if (!semLacuna || dono.runtime !== 'claude-bg')
|
|
25
|
+
return false;
|
|
26
|
+
return leitura.contas.some(c => c.runtime === 'claude-bg' && (c.perfil?.id ?? null) === dono.perfil);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A ocupação desta máquina agora, relida a cada chamada. `consultar` é dependência dos testes; sem ela, as sessões de
|
|
30
|
+
* todas as contas pelo `consultarContas`, a mesma leitura do escalonador.
|
|
31
|
+
*/
|
|
32
|
+
function fatosDeCapacidade(carregado, opcoes = {}) {
|
|
33
|
+
const quando = opcoes.quando ?? new Date().toISOString();
|
|
34
|
+
const { raiz, manifesto } = carregado;
|
|
35
|
+
const staleMin = manifesto.concurrency.stale_after_min;
|
|
36
|
+
const leitura = (opcoes.consultar ?? (() => (0, sessoes_contas_1.consultarContas)(raiz, { staleMin })))();
|
|
37
|
+
const lacunas = leitura.fontes.filter(f => !f.ok).map(f => `${f.origem}: ${f.detalhe}`);
|
|
38
|
+
const porSessao = new Map(leitura.sessoes.map(s => [s.sessionId, s]));
|
|
39
|
+
const ocupantes = [];
|
|
40
|
+
const encerradasPeloRuntime = [];
|
|
41
|
+
const contadas = new Set();
|
|
42
|
+
// A sessão que a regra da vaga solta (turno encerrado, espera do dono, parada) não volta pela lista do runtime,
|
|
43
|
+
// a não ser que o runtime a mostre trabalhando agora (A8 do CHECK): a regra da vaga lê só o ledger.
|
|
44
|
+
const soltas = new Set();
|
|
45
|
+
for (const id of (0, thread_1.listarIds)(raiz)) {
|
|
46
|
+
let atual = null;
|
|
47
|
+
try {
|
|
48
|
+
atual = (0, conducao_1.conducaoDaThread)(raiz, id);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (!atual)
|
|
54
|
+
continue;
|
|
55
|
+
if (atual.dono.tipo === 'processo' && (atual.operacao === 'phase.run' || atual.operacao === 'retry.run')) {
|
|
56
|
+
ocupantes.push({ sessionId: null, thread: id, runtime: null, conta: null, revisao: atual.fase === 'CHECK', origem: 'despacho' });
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (atual.dono.tipo !== 'sessao')
|
|
60
|
+
continue;
|
|
61
|
+
const dono = atual.dono;
|
|
62
|
+
const vista = porSessao.get(dono.sessionId);
|
|
63
|
+
try {
|
|
64
|
+
if ((0, ocupacao_1.sessaoLivreDaVaga)((0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, id)), atual.desde, quando, staleMin, dono.sessionId) &&
|
|
65
|
+
!(vista?.viva && TRABALHANDO.includes(estadoDe(vista)))) {
|
|
66
|
+
soltas.add(dono.sessionId);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch { /* ledger ilegível: a condução viva continua contando, como no portão do phase run */ }
|
|
71
|
+
if (encerradaPeloRuntime(dono, leitura, porSessao, lacunas.length === 0)) {
|
|
72
|
+
encerradasPeloRuntime.push(dono.sessionId);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
contadas.add(dono.sessionId);
|
|
76
|
+
// A5 do CHECK: o despacho sem `--perfil` grava o lease sem conta; a conta é a que o runtime atribui à sessão.
|
|
77
|
+
ocupantes.push({ sessionId: dono.sessionId, thread: id, runtime: dono.runtime, conta: dono.perfil ?? vista?.perfil ?? null,
|
|
78
|
+
revisao: atual.fase === 'CHECK', origem: 'conducao' });
|
|
79
|
+
}
|
|
80
|
+
for (const s of leitura.sessoes) {
|
|
81
|
+
if (!s.viva || contadas.has(s.sessionId) || soltas.has(s.sessionId) || encerradasPeloRuntime.includes(s.sessionId))
|
|
82
|
+
continue;
|
|
83
|
+
contadas.add(s.sessionId);
|
|
84
|
+
ocupantes.push({ sessionId: s.sessionId, thread: null, runtime: s.runtime, conta: s.perfil, revisao: false, origem: 'runtime' });
|
|
85
|
+
}
|
|
86
|
+
return { quando, ocupantes, lacunas, encerradasPeloRuntime };
|
|
87
|
+
}
|
|
88
|
+
const limiteDe = (lista, chave, nome) => lista.find(x => x[chave] === nome)?.sessoes ?? null;
|
|
89
|
+
/**
|
|
90
|
+
* Cabe mais esta sessão? Todos os limites ao mesmo tempo, na ordem: leitura completa, conta e runtime autorizados,
|
|
91
|
+
* o projeto (o portão do `phase run`, que o chamador consulta para a thread), a máquina, a margem de revisão (a
|
|
92
|
+
* execução não usa os slots reservados ao CHECK), a conta e o runtime.
|
|
93
|
+
*/
|
|
94
|
+
function admitir(pedido, limites, fatos, vagaDoProjeto) {
|
|
95
|
+
if (fatos.lacunas.length) {
|
|
96
|
+
return { ok: false, motivo: 'capacidade.fonte-indisponivel', detalhe: `sessões sem leitura: ${fatos.lacunas.join('; ')}` };
|
|
97
|
+
}
|
|
98
|
+
const limiteDoRuntime = limiteDe(limites.porRuntime, 'runtime', pedido.runtime);
|
|
99
|
+
if (limiteDoRuntime === null) {
|
|
100
|
+
return { ok: false, motivo: 'capacidade.runtime-nao-autorizado', detalhe: `o runtime ${pedido.runtime} não está no envelope` };
|
|
101
|
+
}
|
|
102
|
+
const limiteDaConta = limiteDe(limites.porConta, 'conta', pedido.conta);
|
|
103
|
+
if (limiteDaConta === null) {
|
|
104
|
+
return { ok: false, motivo: 'capacidade.conta-nao-autorizada', detalhe: `a conta ${pedido.conta} não está no envelope` };
|
|
105
|
+
}
|
|
106
|
+
if (vagaDoProjeto)
|
|
107
|
+
return { ok: false, motivo: 'capacidade.projeto', detalhe: vagaDoProjeto.detalhe };
|
|
108
|
+
const total = fatos.ocupantes.length;
|
|
109
|
+
if (total >= limites.maquina) {
|
|
110
|
+
return { ok: false, motivo: 'capacidade.maquina', detalhe: `${total} sessão(ões) nesta máquina e o limite do envelope é ${limites.maquina}` };
|
|
111
|
+
}
|
|
112
|
+
const execucao = fatos.ocupantes.filter(o => !o.revisao).length;
|
|
113
|
+
if (!pedido.revisao && execucao >= limites.maquina - limites.revisao) {
|
|
114
|
+
return { ok: false, motivo: 'capacidade.revisao', detalhe: `${execucao} sessão(ões) de execução e ${limites.revisao} slot(s) ` +
|
|
115
|
+
`reservado(s) à revisão de ${limites.maquina}: só o CHECK usa o que sobra` };
|
|
116
|
+
}
|
|
117
|
+
const naConta = fatos.ocupantes.filter(o => o.conta === pedido.conta).length;
|
|
118
|
+
if (naConta >= limiteDaConta) {
|
|
119
|
+
return { ok: false, motivo: 'capacidade.conta', detalhe: `${naConta} sessão(ões) na conta ${pedido.conta} e o limite é ${limiteDaConta}` };
|
|
120
|
+
}
|
|
121
|
+
const noRuntime = fatos.ocupantes.filter(o => o.runtime === pedido.runtime).length;
|
|
122
|
+
if (noRuntime >= limiteDoRuntime) {
|
|
123
|
+
return { ok: false, motivo: 'capacidade.runtime', detalhe: `${noRuntime} sessão(ões) no ${pedido.runtime} e o limite é ${limiteDoRuntime}` };
|
|
124
|
+
}
|
|
125
|
+
return { ok: true };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A conta do despacho: entre as do envelope que são perfis do runtime (`perfisDoRuntime`, do store de contas), a com
|
|
129
|
+
* mais folga no limite dela; empate pela ordem do envelope. `null` quando nenhuma tem vaga.
|
|
130
|
+
*/
|
|
131
|
+
function escolherConta(limites, fatos, perfisDoRuntime) {
|
|
132
|
+
let melhor = null;
|
|
133
|
+
for (const { conta, sessoes } of limites.porConta) {
|
|
134
|
+
if (!perfisDoRuntime.includes(conta))
|
|
135
|
+
continue;
|
|
136
|
+
const folga = sessoes - fatos.ocupantes.filter(o => o.conta === conta).length;
|
|
137
|
+
if (folga > 0 && (!melhor || folga > melhor.folga))
|
|
138
|
+
melhor = { conta, folga };
|
|
139
|
+
}
|
|
140
|
+
return melhor?.conta ?? null;
|
|
141
|
+
}
|