@orkastery/cli 0.4.2 → 0.5.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 +11 -0
- package/adapters/claude-code/.claude-plugin/plugin.json +3 -1
- package/adapters/claude-code/agents/ork-check.md +1 -1
- package/adapters/claude-code/agents/ork-go.md +2 -2
- package/adapters/claude-code/agents/ork-goal.md +1 -1
- package/adapters/claude-code/agents/ork-master.md +1 -1
- package/adapters/claude-code/agents/ork-plan.md +1 -1
- package/adapters/claude-code/agents/ork-ship.md +1 -1
- package/adapters/claude-code/commands/master.md +11 -8
- package/adapters/claude-code/commands/ork.md +8 -0
- package/adapters/claude-code/commands/ship.md +2 -2
- package/adapters/codex/skills/ork/SKILL.md +12 -1
- package/adapters/hermes/README.md +3 -0
- package/adapters/hermes/bin/ork-abrir-thread.sh +17 -2
- package/adapters/hermes/bin/ork-brain.sh +3 -0
- package/adapters/hermes/bin/ork-maestro.sh +4 -1
- package/adapters/hermes/bin/ork-network-roadmap.sh +11 -0
- package/adapters/hermes/bin/ork-roadmap-status.sh +9 -0
- package/adapters/hermes/hermes.plugin.json +2 -0
- package/adapters/hermes/hitl-ingress/__init__.py +36 -3
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +19 -20
- package/adapters/openclaw/README.md +34 -3
- package/adapters/openclaw/dist/hitl-ingress.js +37 -3
- package/adapters/openclaw/dist/index.js +92 -39
- package/adapters/openclaw/openclaw.plugin.json +10 -3
- package/adapters/openclaw/package.json +2 -2
- package/adapters/openclaw/src/hitl-ingress.ts +32 -3
- package/adapters/openclaw/src/index.ts +108 -41
- package/assets/docs/padroes/documentacao-de-produto.md +2 -2
- package/assets/docs/padroes/roadmap-de-produto.md +1 -1
- package/assets/docs/produto/_modelo-feature.md +2 -0
- package/assets/orkmind_bridge.py +214 -1
- package/dist/adapters/claude-bg.js +88 -9
- package/dist/adapters/codex-events.js +3 -1
- package/dist/board.js +74 -0
- package/dist/branch-de-estado.js +5 -4
- package/dist/busca-semantica.js +161 -0
- package/dist/ci.js +141 -10
- package/dist/company-brain-cli.js +27 -2
- package/dist/company-brain-context.js +132 -0
- package/dist/company-brain-dossie.js +376 -0
- package/dist/company-brain-mcp.js +4 -1
- package/dist/conducao.js +117 -31
- package/dist/decisao-autonoma.js +42 -0
- package/dist/docs.js +64 -22
- package/dist/doctor.js +33 -0
- package/dist/entrega-pr.js +109 -5
- package/dist/experiencia-instalacao.js +256 -0
- package/dist/experiencia.js +72 -0
- package/dist/fabrica-estado.js +43 -10
- package/dist/fechamento.js +105 -0
- package/dist/fix.js +1 -1
- package/dist/forja.js +435 -0
- package/dist/gates.js +10 -1
- package/dist/hitl-classificacao.js +11 -1
- package/dist/hitl-contract.js +50 -7
- package/dist/hitl-curto.js +158 -0
- package/dist/hitl-gates.js +67 -1
- package/dist/hitl-lote.js +30 -15
- package/dist/hitl-presentation.js +10 -7
- package/dist/hitl-resumo.js +33 -12
- package/dist/hitl-texto-livre.js +150 -0
- package/dist/hosts.js +86 -1
- package/dist/index.js +605 -41
- package/dist/indice-vetorial.js +317 -0
- package/dist/init.js +13 -0
- package/dist/integracoes-locais.js +1 -1
- package/dist/intelligence-benchmark-contract.js +570 -0
- package/dist/intelligence-graph-cli.js +430 -0
- package/dist/intelligence-graph-contract.js +577 -0
- package/dist/intelligence-graph-extract-md.js +469 -0
- package/dist/intelligence-graph-extract-ts.js +810 -0
- package/dist/intelligence-graph-extract.js +369 -0
- package/dist/intelligence-graph-index.js +512 -0
- package/dist/intelligence-graph-parsers.js +327 -0
- package/dist/intelligence-graph-query.js +344 -0
- package/dist/intelligence-graph-repo.js +187 -0
- package/dist/leases.js +84 -0
- package/dist/ledger.js +14 -0
- package/dist/maestro-cli.js +10 -1
- package/dist/maestro-contract.js +5 -1
- package/dist/maestro-discovery.js +16 -2
- package/dist/maestro-snapshot.js +6 -2
- package/dist/manifest.js +142 -5
- package/dist/master-batch.js +3 -2
- package/dist/master-digest.js +2 -2
- package/dist/master-nota.js +203 -0
- package/dist/master.js +4 -0
- package/dist/mcp-experiencia.js +164 -0
- package/dist/mcp-git.js +36 -10
- package/dist/mcp-install.js +3 -1
- package/dist/mcp-maestro.js +3 -2
- package/dist/mcp-server.js +84 -5
- package/dist/memoria.js +147 -1
- package/dist/network-roadmap.js +907 -0
- package/dist/ocupacao.js +38 -2
- package/dist/onboarding.js +113 -7
- package/dist/orkmind.js +165 -9
- package/dist/phase.js +166 -13
- package/dist/policies.js +2 -0
- package/dist/projeto-alvo.js +551 -0
- package/dist/prompts.js +1 -1
- package/dist/pulse-consentimento.js +4 -2
- package/dist/pulse-delivery.js +5 -0
- package/dist/pulse-resposta.js +674 -49
- package/dist/pulse.js +21 -0
- package/dist/ratelimit.js +3 -2
- package/dist/retry.js +230 -9
- package/dist/roadmap-reservas.js +262 -20
- package/dist/roadmap-status.js +213 -0
- package/dist/runtime-ambiente.js +12 -1
- package/dist/session-watcher-claude.js +26 -0
- package/dist/sessoes.js +49 -15
- package/dist/thread-close.js +3 -0
- package/dist/verify.js +5 -4
- package/dist/worktree.js +77 -0
- package/eval/casos/orchestration-experience-pt-br.json +48 -0
- package/eval/casos/orchestration-experience.json +48 -0
- package/package.json +1 -1
- package/schemas/code-artifact-graph.v1.schema.json +581 -0
- package/schemas/graph-benchmark.v1.schema.json +2240 -0
- package/schemas/maestro-snapshot.schema.json +23 -0
- package/skills/README.md +7 -5
- package/skills/core/onboarding/SKILL.md +7 -0
- package/skills/core/orchestration-experience/SKILL.md +113 -0
- package/skills/core/orchestration-experience-pt-br/SKILL.md +112 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
- package/skills/phases/go-implementation/SKILL.md +2 -0
package/dist/mcp-server.js
CHANGED
|
@@ -56,6 +56,8 @@ const leases_1 = require("./leases");
|
|
|
56
56
|
const hitl_gates_1 = require("./hitl-gates");
|
|
57
57
|
const hitl_contract_1 = require("./hitl-contract");
|
|
58
58
|
const hitl_presentation_1 = require("./hitl-presentation");
|
|
59
|
+
const roadmap_status_1 = require("./roadmap-status");
|
|
60
|
+
const network_roadmap_1 = require("./network-roadmap");
|
|
59
61
|
const hitl_sessions_1 = require("./hitl-sessions");
|
|
60
62
|
const hitl_local_1 = require("./hitl-local");
|
|
61
63
|
const mcp_artifacts_1 = require("./mcp-artifacts");
|
|
@@ -65,6 +67,7 @@ const modos_1 = require("./modos");
|
|
|
65
67
|
const versao_1 = require("./versao");
|
|
66
68
|
const mcp_verify_1 = require("./mcp-verify");
|
|
67
69
|
const conducao_1 = require("./conducao");
|
|
70
|
+
const decisao_autonoma_1 = require("./decisao-autonoma");
|
|
68
71
|
const conducao_texto_1 = require("./conducao-texto");
|
|
69
72
|
const mcp_ship_1 = require("./mcp-ship");
|
|
70
73
|
const company_brain_mcp_1 = require("./company-brain-mcp");
|
|
@@ -72,6 +75,8 @@ const claude_bg_1 = require("./adapters/claude-bg");
|
|
|
72
75
|
const session_watcher_claude_1 = require("./session-watcher-claude");
|
|
73
76
|
const runtime_profiles_1 = require("./runtime-profiles");
|
|
74
77
|
const mcp_maestro_1 = require("./mcp-maestro");
|
|
78
|
+
const projeto_alvo_1 = require("./projeto-alvo");
|
|
79
|
+
const mcp_experiencia_1 = require("./mcp-experiencia");
|
|
75
80
|
const identidade = zod_1.z.string().min(1).max(80).regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/);
|
|
76
81
|
const daThread = zod_1.z.object({ threadId: identidade }).strict();
|
|
77
82
|
const daDecisao = daThread.extend({ pedidoId: identidade }).strict();
|
|
@@ -297,15 +302,33 @@ function criarServidorMcp(opcoes) {
|
|
|
297
302
|
throw Error('lease.busy: ' + conflitos.map(l => l.nome + ' (' + l.thread + ')').join(', '));
|
|
298
303
|
}
|
|
299
304
|
};
|
|
300
|
-
const server = new index_js_1.Server({ name: 'orkastery', version: versao_1.VERSAO_DO_ORK }, { capabilities: { tools: {} }, instructions: 'Opere somente este projeto pelas ferramentas do nucleo. Decisoes humanas usam ork_request_decision e o dialogo do host; argumentos de ferramenta nunca sao respostas.' });
|
|
305
|
+
const server = new index_js_1.Server({ name: 'orkastery', version: versao_1.VERSAO_DO_ORK }, { capabilities: { tools: {} }, instructions: 'Opere somente este projeto pelas ferramentas do nucleo. O parametro opcional projeto so confere o projeto servido; nunca troca a raiz. O status do roadmap vem de ork_network_roadmap, transportado como vem. Decisoes humanas usam ork_request_decision e o dialogo do host; argumentos de ferramenta nunca sao respostas.' });
|
|
306
|
+
/**
|
|
307
|
+
* RM-052 (D5): toda tool aceita `projeto`, e ele so CONFERE o projeto fixado no startup. Pedido de
|
|
308
|
+
* outro projeto recusa tipado, com o projeto servido como unico candidato; a raiz nunca muda aqui.
|
|
309
|
+
*/
|
|
310
|
+
const conferirProjeto = (pedido) => {
|
|
311
|
+
const c = carregar(), nome = c.manifesto.project.name, abbrev = c.manifesto.project.abbrev, v = pedido.toLowerCase();
|
|
312
|
+
if (nome.toLowerCase() === v || (!!abbrev && abbrev.toLowerCase() === v))
|
|
313
|
+
return;
|
|
314
|
+
throw new projeto_alvo_1.ErroDeProjeto('projeto.fora-do-servidor', `este servidor MCP atende somente o projeto ${nome}; "${pedido}" nao e ele`, [{ nome, abbrev, raiz: (0, projeto_alvo_1.raizParaExibir)(raiz), remoto: (0, projeto_alvo_1.remotoDoProjeto)(raiz, c.manifesto.fabrica?.remoto ?? 'origin'), presente: true }], 'Use o servidor MCP instalado no outro projeto (ork mcp install --project <raiz>), ou o CLI com --projeto <nome>.');
|
|
315
|
+
};
|
|
316
|
+
const campoProjeto = zod_1.z.string().regex(projeto_alvo_1.PADRAO_DO_NOME_DE_PROJETO)
|
|
317
|
+
.describe('Nome ou abbrev do projeto pedido; este servidor atende somente o projeto fixado na instalacao');
|
|
301
318
|
const ferramentas = new Map();
|
|
302
319
|
function registrarTool(nome, config, executar) {
|
|
303
320
|
if (opcoes.threadId && ['ork_thread_new', 'ork_phase_run', 'ork_request_decision', 'ork_preflight'].includes(nome))
|
|
304
321
|
return;
|
|
305
|
-
const
|
|
322
|
+
const entrada = config.inputSchema.extend({ projeto: campoProjeto.optional() });
|
|
323
|
+
const schema = converterSchema(entrada, { $refStrategy: 'none' });
|
|
306
324
|
ferramentas.set(nome, { tool: { name: nome, description: config.description, annotations: config.annotations,
|
|
307
325
|
inputSchema: schema },
|
|
308
|
-
executar: async (raw, extra) =>
|
|
326
|
+
executar: async (raw, extra) => {
|
|
327
|
+
const { projeto, ...args } = entrada.parse(raw);
|
|
328
|
+
if (projeto !== undefined)
|
|
329
|
+
conferirProjeto(projeto);
|
|
330
|
+
return executar(args, extra);
|
|
331
|
+
} });
|
|
309
332
|
}
|
|
310
333
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({ tools: [...ferramentas.values()].map(f => f.tool) }));
|
|
311
334
|
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request, extra) => {
|
|
@@ -316,6 +339,8 @@ function criarServidorMcp(opcoes) {
|
|
|
316
339
|
return await f.executar(request.params.arguments ?? {}, extra);
|
|
317
340
|
}
|
|
318
341
|
catch (e) {
|
|
342
|
+
if (e instanceof projeto_alvo_1.ErroDeProjeto)
|
|
343
|
+
return { ...resposta(e.recusa), isError: true };
|
|
319
344
|
return { ...resposta({ erro: e.message }), isError: true };
|
|
320
345
|
}
|
|
321
346
|
});
|
|
@@ -344,6 +369,7 @@ function criarServidorMcp(opcoes) {
|
|
|
344
369
|
});
|
|
345
370
|
server.onclose = () => ingresso.fechar();
|
|
346
371
|
(0, company_brain_mcp_1.registerBrainTools)(registrarTool, carregar, thread, opcoes.brainWrites ?? []);
|
|
372
|
+
(0, mcp_experiencia_1.registrarConsultasExperiencia)(registrarTool, { raiz, carregar, transporte: opcoes.transporteShip ?? 'github-ssh' });
|
|
347
373
|
(0, mcp_maestro_1.registerMaestro)(registrarTool, { root: raiz, threadId: opcoes.threadId, load: carregar, checkThread: thread, tools: () => [...ferramentas.keys()] });
|
|
348
374
|
registrarTool('ork_preflight', { description: 'Preflight contextual por modo e bloco, sem inventário global/modelos. Não autoriza despacho nem comprova entrega.',
|
|
349
375
|
inputSchema: zod_1.z.object({ modo: modoDeConducao }).strict(), annotations: { readOnlyHint: true } }, async ({ modo }) => {
|
|
@@ -402,6 +428,35 @@ function criarServidorMcp(opcoes) {
|
|
|
402
428
|
livre(threadId);
|
|
403
429
|
return resposta((0, mcp_artifacts_1.escreverArtefatoMcp)(raiz, threadId, tipo, conteudo, expectedSha256));
|
|
404
430
|
});
|
|
431
|
+
// RM-037 (rm037defeito, defeito 1): a decisao que a sessao toma sem perguntar ao dono. O sandbox do
|
|
432
|
+
// codex nao grava o ledger e o `ork decisao registrar` morria em EROFS. Mesma `registrarDecisao` do CLI:
|
|
433
|
+
// contrato v2, criterio que resolve e rastro no mesmo evento. Nao pergunta ao dono e nao toca gate.
|
|
434
|
+
const campoDaDecisao = zod_1.z.string().min(1).max(4096);
|
|
435
|
+
registrarTool('ork_decision_record', { description: 'Registra decisao ja tomada pela sessao sem perguntar ao dono (classe decidido), com criterio que resolve e rastro. Nao pergunta, nao responde nem aprova gate.',
|
|
436
|
+
inputSchema: daThread.extend({ decidido: campoDaDecisao, porque: campoDaDecisao, comoMudar: campoDaDecisao,
|
|
437
|
+
custoAgora: campoDaDecisao, custoDepois: campoDaDecisao,
|
|
438
|
+
criterio: zod_1.z.object({ tipo: zod_1.z.enum(['manifesto', 'ledger', 'medicao']), referencia: campoDaDecisao }).strict(),
|
|
439
|
+
quemDecidiu: zod_1.z.string().min(1).max(200), evidencia: campoDaDecisao, razao: campoDaDecisao.optional(),
|
|
440
|
+
reverte: zod_1.z.string().min(1).max(80).optional() }).strict(),
|
|
441
|
+
annotations: { readOnlyHint: false, destructiveHint: false } }, async ({ threadId, ...e }) => {
|
|
442
|
+
thread(threadId);
|
|
443
|
+
livre(threadId);
|
|
444
|
+
// A sessao decide por ela: o rastro nao pode nascer assinado em nome do dono.
|
|
445
|
+
if (/^\s*(?:o\s+|a\s+)?(?:dono|owner|builder|maestro)\b/i.test(e.quemDecidiu))
|
|
446
|
+
throw Error('mcp.decision.author: quemDecidiu e a sessao que decidiu, nunca o dono');
|
|
447
|
+
let registro;
|
|
448
|
+
try {
|
|
449
|
+
registro = (0, decisao_autonoma_1.registrarDecisao)(raiz, threadId, { decidido: e.decidido, porque: e.porque, comoMudar: e.comoMudar,
|
|
450
|
+
custoDeReverter: { agora: e.custoAgora, depois: e.custoDepois }, criterio: e.criterio, quemDecidiu: e.quemDecidiu,
|
|
451
|
+
evidencia: e.evidencia, ...(e.razao ? { razao: e.razao } : {}), ...(e.reverte ? { reverte: e.reverte } : {}), origem: 'mcp', host: opcoes.host,
|
|
452
|
+
despacho: opcoes.dispatchId ?? null });
|
|
453
|
+
}
|
|
454
|
+
catch (erro) {
|
|
455
|
+
throw Error((0, hitl_contract_1.recusaNaSuperficie)(erro.message, hitl_contract_1.CAMPOS_DA_DECISAO_NO_MCP));
|
|
456
|
+
}
|
|
457
|
+
const { pedido, evento } = registro;
|
|
458
|
+
return resposta({ ok: true, pedidoId: pedido.id, eventId: evento.eventId, fase: pedido.fase, reciboOficial: false });
|
|
459
|
+
});
|
|
405
460
|
registrarTool('ork_claims_list', { description: 'Lista alegacoes e seu estado de verificacao registrado pelo nucleo.',
|
|
406
461
|
inputSchema: daThread, annotations: { readOnlyHint: true } }, async ({ threadId }) => {
|
|
407
462
|
thread(threadId);
|
|
@@ -423,6 +478,25 @@ function criarServidorMcp(opcoes) {
|
|
|
423
478
|
});
|
|
424
479
|
registrarTool('ork_hitl_pending', { description: 'Pedidos HITL atuais da thread, incluindo prazo; nao aprova nem abre pedido.',
|
|
425
480
|
inputSchema: daThread, annotations: { readOnlyHint: true } }, async ({ threadId }) => resposta({ threadId, pendencias: pendencias(threadId) }));
|
|
481
|
+
registrarTool('ork_roadmap_status', { description: 'Status report do roadmap SO desta maquina (o checkout local), no formato aprovado pelo dono: grupos com icones, #HITL no que espera o dono e o fecho. Somente leitura; transporte o texto como vem. O cabecalho diz o projeto consultado e o que nao foi lido (reservas, outras maquinas). Para o status do roadmap com as threads de todas as maquinas, as reservas, as fontes e as lacunas, use ork_network_roadmap; nunca conclua sobre ele a partir de ork_maestro ou de threads.',
|
|
482
|
+
inputSchema: zod_1.z.object({}).strict(), annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false } }, async () => {
|
|
483
|
+
const c = carregar();
|
|
484
|
+
// RM-052: origem `instalacao`; o servidor fixado nao revela os outros projetos da maquina.
|
|
485
|
+
const consulta = (0, projeto_alvo_1.consultaDoProjeto)(c, { origem: 'instalacao', outrosProjetos: false,
|
|
486
|
+
lido: ['roadmap (docs/roadmap)', projeto_alvo_1.FORA_DA_CONSULTA.threadsDaMaquina], naoLido: [projeto_alvo_1.FORA_DA_CONSULTA.reservas, 'threads de outras máquinas (ork network roadmap)'] });
|
|
487
|
+
const status = (0, roadmap_status_1.montarStatusDoRoadmap)(raiz, { projeto: c.manifesto.project.name, consulta });
|
|
488
|
+
return resposta({ texto: (0, roadmap_status_1.textoDoStatusDoRoadmap)(status), status });
|
|
489
|
+
});
|
|
490
|
+
/**
|
|
491
|
+
* RM-054 (fatia 2, D-G5): o roadmap da rede do projeto servido, em todas as maquinas dele. O servidor
|
|
492
|
+
* fixado nao le o registro nem revela os outros projetos (D5 da RM-052); o texto e o do CLI.
|
|
493
|
+
*/
|
|
494
|
+
registrarTool('ork_network_roadmap', { description: 'Roadmap da rede do projeto servido, somente leitura: o status report do roadmap (RM-048) com as threads de TODAS as maquinas, as reservas, as threads por maquina com a idade da batida, a fonte e a hora de cada parte e as lacunas tipadas. E a fonte do status do roadmap: transporte o texto como vem, sem reescrever nem resumir. Lacuna e "Nao consultado" sao o que nao foi lido: nunca conclua "roadmap vazio" nem "nenhuma maquina publicou" a partir deles. Este servidor le so o projeto fixado; os outros projetos vem do CLI ork network roadmap.',
|
|
495
|
+
inputSchema: zod_1.z.object({}).strict(), annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true } }, async () => {
|
|
496
|
+
carregar();
|
|
497
|
+
const panorama = (0, network_roadmap_1.montarPanoramaDaRede)({ fixado: raiz });
|
|
498
|
+
return resposta({ texto: (0, network_roadmap_1.textoDoPanoramaDaRede)(panorama), panorama });
|
|
499
|
+
});
|
|
426
500
|
registrarTool('ork_observe', { description: 'Observa uma vez o progresso canonico e pedidos da thread. Nao cria monitor ou despacho.',
|
|
427
501
|
inputSchema: daThread, annotations: { readOnlyHint: true } }, async ({ threadId }) => {
|
|
428
502
|
return resposta(observar(threadId));
|
|
@@ -439,14 +513,19 @@ function criarServidorMcp(opcoes) {
|
|
|
439
513
|
while (!fs.existsSync(existente))
|
|
440
514
|
existente = path.dirname(existente);
|
|
441
515
|
confinado(existente);
|
|
442
|
-
|
|
516
|
+
const criada = (0, thread_1.novaThread)(c, { nome, modo: modo ?? c.manifesto.conduction.default_mode, criarWorktree: true });
|
|
517
|
+
// RM-052 (D7): thread nova, projeto conhecido pelo nome nesta maquina; o registro nunca derruba a criacao.
|
|
518
|
+
if (criada.gravada)
|
|
519
|
+
(0, projeto_alvo_1.registrarProjetoEmSilencio)(raiz, 'mcp thread new');
|
|
520
|
+
return resposta(criada);
|
|
443
521
|
});
|
|
444
522
|
registrarTool('ork_phase_run', { description: 'Despacha fase autorizada pelo nucleo, preservando policies, estado e runtime/modelo. dryRun nao inicia modelo, mas pode registrar prompt/eventos.',
|
|
445
523
|
inputSchema: fase, annotations: { readOnlyHint: false, destructiveHint: false } }, async (args) => {
|
|
446
524
|
const t = thread(args.threadId);
|
|
447
525
|
livre(t.id);
|
|
448
526
|
const { threadId, fase: f, ...op } = args;
|
|
449
|
-
|
|
527
|
+
// RM-037 (A3): o MCP nao roda a suite para a baseline do despacho; a falta dela volta como pendencia.
|
|
528
|
+
return resposta((0, phase_1.rodarFase)(carregar(), threadId, { ...op, fase: (0, thread_1.exigirFase)(t, f), canal: conducao.canal, baselinePeloDespacho: false }));
|
|
450
529
|
});
|
|
451
530
|
registrarTool('ork_gate_request', { description: 'Abre pedido de gate somente quando pausa ou escalacao tipada esta comprovada no nucleo; nao aprova.',
|
|
452
531
|
inputSchema: daThread.extend({ motivo: zod_1.z.enum(['human.pending', 'policy.violation', 'cost.violation',
|
package/dist/memoria.js
CHANGED
|
@@ -35,6 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.sincronizarOnboarding = sincronizarOnboarding;
|
|
37
37
|
exports.abrirMemoria = abrirMemoria;
|
|
38
|
+
exports.estadoDeEmbeddings = estadoDeEmbeddings;
|
|
39
|
+
exports.sondarEmbeddings = sondarEmbeddings;
|
|
38
40
|
exports.tagsDoProjeto = tagsDoProjeto;
|
|
39
41
|
exports.situacaoDaThread = situacaoDaThread;
|
|
40
42
|
exports.situacaoDaFase = situacaoDaFase;
|
|
@@ -64,6 +66,7 @@ exports.sincronizarMemoria = sincronizarMemoria;
|
|
|
64
66
|
exports.publicar = publicar;
|
|
65
67
|
exports.publicarPropostas = publicarPropostas;
|
|
66
68
|
exports.textoDoEstado = textoDoEstado;
|
|
69
|
+
exports.textoDosEmbeddings = textoDosEmbeddings;
|
|
67
70
|
exports.textoDoSync = textoDoSync;
|
|
68
71
|
exports.parsePrioridade = parsePrioridade;
|
|
69
72
|
const write_activation_1 = require("./write-activation");
|
|
@@ -97,6 +100,7 @@ const memoria_humana_1 = require("./memoria-humana");
|
|
|
97
100
|
const master_1 = require("./master");
|
|
98
101
|
const modos_1 = require("./modos");
|
|
99
102
|
const orkmind_1 = require("./orkmind");
|
|
103
|
+
const indice_vetorial_1 = require("./indice-vetorial");
|
|
100
104
|
const ledger_1 = require("./ledger");
|
|
101
105
|
const thread_1 = require("./thread");
|
|
102
106
|
const util_1 = require("./util");
|
|
@@ -167,6 +171,10 @@ function abrirMemoria(carregado, opcoes = {}) {
|
|
|
167
171
|
const leituraRestrita = resolverLeituraRestrita(carregado.manifesto, opcoes.leituraRestrita);
|
|
168
172
|
const { estado, driver } = (0, orkmind_1.resolverRegime)(carregado.manifesto, opcoes.driver ?? null);
|
|
169
173
|
const ativo = estado.efetivo === 'orkmind' && driver !== null;
|
|
174
|
+
const config = (0, orkmind_1.configDoManifesto)(carregado.manifesto);
|
|
175
|
+
const embeddings = (universo) => estadoDeEmbeddings(carregado.manifesto, ativo ? driver?.disponivel().saude ?? null : null, carregado.raiz, estado.tenant, config.dsn, { universo });
|
|
176
|
+
if (estado.pedido === 'orkmind')
|
|
177
|
+
estado.embeddings = embeddings();
|
|
170
178
|
const consultarRestrito = (collection, tags) => {
|
|
171
179
|
if (!leituraRestrita)
|
|
172
180
|
throw Error('memory.query.invalid');
|
|
@@ -178,7 +186,7 @@ function abrirMemoria(carregado, opcoes = {}) {
|
|
|
178
186
|
throw Error('memory.query.unsupported');
|
|
179
187
|
return (0, orkmind_1.concluirConsultaDelimitada)(driver.consultar(q), q);
|
|
180
188
|
};
|
|
181
|
-
|
|
189
|
+
const memoria = {
|
|
182
190
|
configSource: context.source,
|
|
183
191
|
configDivergent: context.divergent,
|
|
184
192
|
get leituraRestrita() { return leituraRestrita; },
|
|
@@ -243,6 +251,114 @@ function abrirMemoria(carregado, opcoes = {}) {
|
|
|
243
251
|
return driver.exportar(colecao).find((e) => e.id === id) ?? null;
|
|
244
252
|
},
|
|
245
253
|
};
|
|
254
|
+
// A cobertura precisa do universo do tenant (um export por colecao): so quando pedida.
|
|
255
|
+
if (opcoes.embeddings === 'detalhado' && ativo && !leituraRestrita) {
|
|
256
|
+
estado.embeddings = embeddings((0, indice_vetorial_1.universoDoTenant)(memoria, estado.tenant));
|
|
257
|
+
}
|
|
258
|
+
return memoria;
|
|
259
|
+
}
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
// I-38 (T4, D6): estado sondado dos embeddings. Nunca derruba o regime.
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
/** Os indices locais do tenant nesta base, por modelo e dimensao. */
|
|
264
|
+
function indicesDoTenant(raiz, tenant, base, universo) {
|
|
265
|
+
const dir = (0, indice_vetorial_1.dirDosIndices)(raiz, tenant);
|
|
266
|
+
if (!fs.existsSync(dir))
|
|
267
|
+
return [];
|
|
268
|
+
const indices = [];
|
|
269
|
+
for (const nome of fs.readdirSync(dir).filter(n => n.endsWith('.json')).sort()) {
|
|
270
|
+
try {
|
|
271
|
+
const bruto = JSON.parse(fs.readFileSync(path.join(dir, nome), 'utf8'));
|
|
272
|
+
if (bruto.contrato !== indice_vetorial_1.CONTRATO_INDICE || bruto.tenant !== tenant || bruto.base !== base)
|
|
273
|
+
continue;
|
|
274
|
+
const { indice } = (0, indice_vetorial_1.lerIndice)(path.join(dir, nome), { tenant, base, modelo: bruto.modelo, dim: bruto.dim });
|
|
275
|
+
const vetores = Object.keys(indice.entradas).length;
|
|
276
|
+
const coerentes = (0, indice_vetorial_1.vetoresCoerentes)(indice, universo).size;
|
|
277
|
+
indices.push({ modelo: indice.modelo, dim: indice.dim, vetores, coerentes, desatualizados: vetores - coerentes });
|
|
278
|
+
}
|
|
279
|
+
catch { /* arquivo ilegivel nao e indice: `ork memory index` o reconstroi */ }
|
|
280
|
+
}
|
|
281
|
+
return indices;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Estado de embeddings: configuracao, presenca da chave (nome, nunca valor), a sonda `health`
|
|
285
|
+
* da ponte e os arquivos de indice. `saude` null quer dizer que a ponte nao foi sondada.
|
|
286
|
+
*/
|
|
287
|
+
function estadoDeEmbeddings(manifesto, saude, raiz, tenant, dsn, opcoes = {}) {
|
|
288
|
+
const config = (0, manifest_1.configDeEmbedding)(manifesto);
|
|
289
|
+
const env = opcoes.env ?? process.env;
|
|
290
|
+
const configurado = config.provider !== 'none';
|
|
291
|
+
const variavel = config.api_key_env;
|
|
292
|
+
const bruto = variavel ? (env[variavel] ?? '').trim() : '';
|
|
293
|
+
const chavePresente = !!variavel && (0, orkmind_1.chaveDeEmbeddingAceita)(bruto, dsn);
|
|
294
|
+
const recusada = bruto !== '' && !chavePresente;
|
|
295
|
+
const dimLocal = configurado && config.fallback_model ? (0, indice_vetorial_1.dimDoModeloLocal)(config.fallback_model, env) : null;
|
|
296
|
+
const dependencias = saude?.fallback.dependencias ?? false;
|
|
297
|
+
const fallback = { modelo: config.fallback_model || null, presente: dimLocal !== null, dependencias, dim: dimLocal };
|
|
298
|
+
const base = (0, indice_vetorial_1.impressaoDaBase)(dsn);
|
|
299
|
+
const existe = (modelo, dim) => dim !== null && fs.existsSync((0, indice_vetorial_1.arquivoDoIndice)(raiz, tenant, modelo, dim));
|
|
300
|
+
const estado = {
|
|
301
|
+
configurado, provider: config.provider, modelo: configurado ? config.model : null, dim: configurado ? config.dim : null,
|
|
302
|
+
variavelDaChave: variavel, chavePresente, fallback, indices: [], entradas: null, cobertura: null,
|
|
303
|
+
ativo: 'nenhum', sondado: saude !== null, motivo: null, detalhe: '', correcao: '',
|
|
304
|
+
};
|
|
305
|
+
if (!configurado) {
|
|
306
|
+
return { ...estado, motivo: 'embeddings.nao-configurado',
|
|
307
|
+
detalhe: 'memory.embedding ausente ou provider none: busca por significado desligada; o recall por tag segue identico',
|
|
308
|
+
correcao: 'declare memory.embedding no manifesto (provider openrouter e api_key_env com o NOME da variavel da chave)' };
|
|
309
|
+
}
|
|
310
|
+
const fallbackUsavel = saude !== null && fallback.presente && dependencias;
|
|
311
|
+
if (chavePresente) {
|
|
312
|
+
estado.ativo = 'primario';
|
|
313
|
+
if (!existe(config.model, config.dim)) {
|
|
314
|
+
estado.motivo = 'embeddings.indice-ausente';
|
|
315
|
+
estado.detalhe = `chave presente em ${variavel}; o indice local de ${config.model} ainda nao existe`;
|
|
316
|
+
estado.correcao = 'rode ork memory index (use --dry-run antes para ver tokens e custo)';
|
|
317
|
+
}
|
|
318
|
+
else
|
|
319
|
+
estado.detalhe = `primario ${config.model} (${config.dim} dim) pela chave em ${variavel}`;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
estado.ativo = fallbackUsavel ? 'fallback' : 'nenhum';
|
|
323
|
+
estado.motivo = 'embeddings.chave-ausente';
|
|
324
|
+
const local = !fallback.modelo ? 'sem fallback local declarado: a busca por significado cai para FTS'
|
|
325
|
+
: !fallback.presente ? `fallback ${fallback.modelo} ausente do cache local: a busca cai para FTS`
|
|
326
|
+
: !saude ? 'ponte nao sondada: fallback local nao conferido'
|
|
327
|
+
: !dependencias ? `fallback ${fallback.modelo} sem torch/transformers no interpretador da ponte: a busca cai para FTS`
|
|
328
|
+
: `busca usa o fallback local ${fallback.modelo} (${fallback.dim} dim)` +
|
|
329
|
+
(existe(fallback.modelo, fallback.dim) ? '' : '; indice local ausente: rode ork memory index --modelo fallback');
|
|
330
|
+
estado.detalhe = `${variavel} ${recusada ? 'tem valor recusado (parece URL, DSN ou texto com espaco; nunca impresso)' : 'nao esta no ambiente (valor nunca impresso)'}; ${local}`;
|
|
331
|
+
estado.correcao = `exporte ${variavel} com a chave dedicada ao Orkastery; o valor nunca vai ao manifesto`;
|
|
332
|
+
}
|
|
333
|
+
if (opcoes.universo) {
|
|
334
|
+
const universo = opcoes.universo.filter(e => (e.tags.project ?? []).includes(tenant));
|
|
335
|
+
estado.indices = indicesDoTenant(raiz, tenant, base, universo);
|
|
336
|
+
estado.entradas = universo.length;
|
|
337
|
+
const referencia = estado.ativo === 'fallback' ? { modelo: fallback.modelo, dim: fallback.dim } : { modelo: config.model, dim: config.dim };
|
|
338
|
+
const indice = estado.indices.find(i => i.modelo === referencia.modelo && i.dim === referencia.dim);
|
|
339
|
+
estado.cobertura = universo.length === 0 ? 0 : Math.round(((indice?.coerentes ?? 0) / universo.length) * 10_000) / 10_000;
|
|
340
|
+
}
|
|
341
|
+
return estado;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* `ork memory status --sondar`: UMA chamada real com texto fixo curto pelo caminho ativo, com
|
|
345
|
+
* a latencia medida (primario custa cerca de US$ 0,00000005; fallback local, so CPU).
|
|
346
|
+
*/
|
|
347
|
+
function sondarEmbeddings(manifesto, estado, embeddar, timeoutMs) {
|
|
348
|
+
if (estado.ativo === 'nenhum')
|
|
349
|
+
return { ok: false, alvo: null, latenciaMs: null, motivo: estado.motivo };
|
|
350
|
+
const config = (0, manifest_1.configDeEmbedding)(manifesto);
|
|
351
|
+
const primario = estado.ativo === 'primario';
|
|
352
|
+
const modelo = primario ? config.model : estado.fallback.modelo;
|
|
353
|
+
const dim = primario ? config.dim : estado.fallback.dim;
|
|
354
|
+
const inicio = Date.now();
|
|
355
|
+
try {
|
|
356
|
+
embeddar({ papel: 'consulta', alvo: estado.ativo, modelo, dim, textos: ['sonda de saude do ork'] }, { timeoutMs });
|
|
357
|
+
return { ok: true, alvo: estado.ativo, latenciaMs: Date.now() - inicio, motivo: null };
|
|
358
|
+
}
|
|
359
|
+
catch (erro) {
|
|
360
|
+
return { ok: false, alvo: estado.ativo, latenciaMs: Date.now() - inicio, motivo: (0, indice_vetorial_1.codigoDeEmbedding)(erro) };
|
|
361
|
+
}
|
|
246
362
|
}
|
|
247
363
|
// ---------------------------------------------------------------------------
|
|
248
364
|
// Tags: as 5 dimensoes, montadas em um lugar so.
|
|
@@ -968,8 +1084,38 @@ function textoDoEstado(estado) {
|
|
|
968
1084
|
linhas.push(` colecoes gravadas: ${orkmind_1.COLECOES_DO_ORK.join(', ')}`);
|
|
969
1085
|
linhas.push(' governanca: source=agent; decision/human exige human_gate comprovado; mandatory=false e regra nunca critical.');
|
|
970
1086
|
}
|
|
1087
|
+
if (estado.embeddings)
|
|
1088
|
+
linhas.push('', ...textoDosEmbeddings(estado.embeddings));
|
|
971
1089
|
return linhas.join('\n');
|
|
972
1090
|
}
|
|
1091
|
+
/** Secao de embeddings do `ork memory status` (I-38 D6): nome da variavel, nunca o valor. */
|
|
1092
|
+
function textoDosEmbeddings(e) {
|
|
1093
|
+
const linhas = ['Busca por significado (embeddings, nao deterministica; o recall por tag nao muda)', ''];
|
|
1094
|
+
linhas.push(` provider ${e.configurado ? `${e.provider} ${e.modelo} (${e.dim} dim)` : 'none (desligada)'}`);
|
|
1095
|
+
if (e.configurado) {
|
|
1096
|
+
linhas.push(` chave ${e.variavelDaChave} ${e.chavePresente ? 'presente' : 'ausente'} no ambiente (valor nunca impresso)`);
|
|
1097
|
+
linhas.push(` fallback local ${e.fallback.modelo ? `${e.fallback.modelo}: ${e.fallback.presente ? `no cache (${e.fallback.dim} dim)` : 'ausente do cache'}, ` +
|
|
1098
|
+
`dependencias ${e.fallback.dependencias ? 'ok' : e.sondado ? 'ausentes' : 'nao sondadas'}` : '(nao declarado)'}`);
|
|
1099
|
+
linhas.push(` caminho ativo ${e.ativo}${e.sondado ? '' : ' (ponte nao sondada)'}`);
|
|
1100
|
+
}
|
|
1101
|
+
for (const i of e.indices) {
|
|
1102
|
+
linhas.push(` indice ${i.modelo} / ${i.dim} dim: ${i.vetores} vetor(es), ${i.coerentes ?? '?'} coerente(s), ${i.desatualizados ?? '?'} desatualizado(s)`);
|
|
1103
|
+
}
|
|
1104
|
+
if (e.entradas !== null) {
|
|
1105
|
+
linhas.push(` cobertura ${e.cobertura === null ? '-' : `${Math.round(e.cobertura * 1000) / 10}%`} de ${e.entradas} entrada(s) do tenant`);
|
|
1106
|
+
}
|
|
1107
|
+
if (e.sonda) {
|
|
1108
|
+
linhas.push(` sonda ${e.sonda.ok ? `${e.sonda.alvo} respondeu em ${e.sonda.latenciaMs} ms` : `sem resposta (${e.sonda.motivo ?? 'sem caminho ativo'})`}`);
|
|
1109
|
+
}
|
|
1110
|
+
if (e.motivo) {
|
|
1111
|
+
linhas.push(` motivo ${e.motivo}`);
|
|
1112
|
+
linhas.push(` ${e.detalhe}`);
|
|
1113
|
+
linhas.push(` correcao: ${e.correcao}`);
|
|
1114
|
+
}
|
|
1115
|
+
else
|
|
1116
|
+
linhas.push(` ${e.detalhe}`);
|
|
1117
|
+
return linhas;
|
|
1118
|
+
}
|
|
973
1119
|
/** Texto de `ork memory sync`. */
|
|
974
1120
|
function textoDoSync(r) {
|
|
975
1121
|
const linhas = [];
|