@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.
Files changed (128) hide show
  1. package/adapters/README.md +11 -0
  2. package/adapters/claude-code/.claude-plugin/plugin.json +3 -1
  3. package/adapters/claude-code/agents/ork-check.md +1 -1
  4. package/adapters/claude-code/agents/ork-go.md +2 -2
  5. package/adapters/claude-code/agents/ork-goal.md +1 -1
  6. package/adapters/claude-code/agents/ork-master.md +1 -1
  7. package/adapters/claude-code/agents/ork-plan.md +1 -1
  8. package/adapters/claude-code/agents/ork-ship.md +1 -1
  9. package/adapters/claude-code/commands/master.md +11 -8
  10. package/adapters/claude-code/commands/ork.md +8 -0
  11. package/adapters/claude-code/commands/ship.md +2 -2
  12. package/adapters/codex/skills/ork/SKILL.md +12 -1
  13. package/adapters/hermes/README.md +3 -0
  14. package/adapters/hermes/bin/ork-abrir-thread.sh +17 -2
  15. package/adapters/hermes/bin/ork-brain.sh +3 -0
  16. package/adapters/hermes/bin/ork-maestro.sh +4 -1
  17. package/adapters/hermes/bin/ork-network-roadmap.sh +11 -0
  18. package/adapters/hermes/bin/ork-roadmap-status.sh +9 -0
  19. package/adapters/hermes/hermes.plugin.json +2 -0
  20. package/adapters/hermes/hitl-ingress/__init__.py +36 -3
  21. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +19 -20
  22. package/adapters/openclaw/README.md +34 -3
  23. package/adapters/openclaw/dist/hitl-ingress.js +37 -3
  24. package/adapters/openclaw/dist/index.js +92 -39
  25. package/adapters/openclaw/openclaw.plugin.json +10 -3
  26. package/adapters/openclaw/package.json +2 -2
  27. package/adapters/openclaw/src/hitl-ingress.ts +32 -3
  28. package/adapters/openclaw/src/index.ts +108 -41
  29. package/assets/docs/padroes/documentacao-de-produto.md +2 -2
  30. package/assets/docs/padroes/roadmap-de-produto.md +1 -1
  31. package/assets/docs/produto/_modelo-feature.md +2 -0
  32. package/assets/orkmind_bridge.py +214 -1
  33. package/dist/adapters/claude-bg.js +88 -9
  34. package/dist/adapters/codex-events.js +3 -1
  35. package/dist/board.js +74 -0
  36. package/dist/branch-de-estado.js +5 -4
  37. package/dist/busca-semantica.js +161 -0
  38. package/dist/ci.js +141 -10
  39. package/dist/company-brain-cli.js +27 -2
  40. package/dist/company-brain-context.js +132 -0
  41. package/dist/company-brain-dossie.js +376 -0
  42. package/dist/company-brain-mcp.js +4 -1
  43. package/dist/conducao.js +117 -31
  44. package/dist/decisao-autonoma.js +42 -0
  45. package/dist/docs.js +64 -22
  46. package/dist/doctor.js +33 -0
  47. package/dist/entrega-pr.js +109 -5
  48. package/dist/experiencia-instalacao.js +256 -0
  49. package/dist/experiencia.js +72 -0
  50. package/dist/fabrica-estado.js +43 -10
  51. package/dist/fechamento.js +105 -0
  52. package/dist/fix.js +1 -1
  53. package/dist/forja.js +435 -0
  54. package/dist/gates.js +10 -1
  55. package/dist/hitl-classificacao.js +11 -1
  56. package/dist/hitl-contract.js +50 -7
  57. package/dist/hitl-curto.js +158 -0
  58. package/dist/hitl-gates.js +67 -1
  59. package/dist/hitl-lote.js +30 -15
  60. package/dist/hitl-presentation.js +10 -7
  61. package/dist/hitl-resumo.js +33 -12
  62. package/dist/hitl-texto-livre.js +150 -0
  63. package/dist/hosts.js +86 -1
  64. package/dist/index.js +605 -41
  65. package/dist/indice-vetorial.js +317 -0
  66. package/dist/init.js +13 -0
  67. package/dist/integracoes-locais.js +1 -1
  68. package/dist/intelligence-benchmark-contract.js +570 -0
  69. package/dist/intelligence-graph-cli.js +430 -0
  70. package/dist/intelligence-graph-contract.js +577 -0
  71. package/dist/intelligence-graph-extract-md.js +469 -0
  72. package/dist/intelligence-graph-extract-ts.js +810 -0
  73. package/dist/intelligence-graph-extract.js +369 -0
  74. package/dist/intelligence-graph-index.js +512 -0
  75. package/dist/intelligence-graph-parsers.js +327 -0
  76. package/dist/intelligence-graph-query.js +344 -0
  77. package/dist/intelligence-graph-repo.js +187 -0
  78. package/dist/leases.js +84 -0
  79. package/dist/ledger.js +14 -0
  80. package/dist/maestro-cli.js +10 -1
  81. package/dist/maestro-contract.js +5 -1
  82. package/dist/maestro-discovery.js +16 -2
  83. package/dist/maestro-snapshot.js +6 -2
  84. package/dist/manifest.js +142 -5
  85. package/dist/master-batch.js +3 -2
  86. package/dist/master-digest.js +2 -2
  87. package/dist/master-nota.js +203 -0
  88. package/dist/master.js +4 -0
  89. package/dist/mcp-experiencia.js +164 -0
  90. package/dist/mcp-git.js +36 -10
  91. package/dist/mcp-install.js +3 -1
  92. package/dist/mcp-maestro.js +3 -2
  93. package/dist/mcp-server.js +84 -5
  94. package/dist/memoria.js +147 -1
  95. package/dist/network-roadmap.js +907 -0
  96. package/dist/ocupacao.js +38 -2
  97. package/dist/onboarding.js +113 -7
  98. package/dist/orkmind.js +165 -9
  99. package/dist/phase.js +166 -13
  100. package/dist/policies.js +2 -0
  101. package/dist/projeto-alvo.js +551 -0
  102. package/dist/prompts.js +1 -1
  103. package/dist/pulse-consentimento.js +4 -2
  104. package/dist/pulse-delivery.js +5 -0
  105. package/dist/pulse-resposta.js +674 -49
  106. package/dist/pulse.js +21 -0
  107. package/dist/ratelimit.js +3 -2
  108. package/dist/retry.js +230 -9
  109. package/dist/roadmap-reservas.js +262 -20
  110. package/dist/roadmap-status.js +213 -0
  111. package/dist/runtime-ambiente.js +12 -1
  112. package/dist/session-watcher-claude.js +26 -0
  113. package/dist/sessoes.js +49 -15
  114. package/dist/thread-close.js +3 -0
  115. package/dist/verify.js +5 -4
  116. package/dist/worktree.js +77 -0
  117. package/eval/casos/orchestration-experience-pt-br.json +48 -0
  118. package/eval/casos/orchestration-experience.json +48 -0
  119. package/package.json +1 -1
  120. package/schemas/code-artifact-graph.v1.schema.json +581 -0
  121. package/schemas/graph-benchmark.v1.schema.json +2240 -0
  122. package/schemas/maestro-snapshot.schema.json +23 -0
  123. package/skills/README.md +7 -5
  124. package/skills/core/onboarding/SKILL.md +7 -0
  125. package/skills/core/orchestration-experience/SKILL.md +113 -0
  126. package/skills/core/orchestration-experience-pt-br/SKILL.md +112 -0
  127. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  128. package/skills/phases/go-implementation/SKILL.md +2 -0
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+ /**
3
+ * I-38 (T3, D2, D10, D11): indice vetorial LOCAL e DERIVADO da memoria do tenant.
4
+ *
5
+ * A DSN declarada le e nao escreve (medido no PLAN), e a coluna `embedding` da base
6
+ * compartilhada guarda vetores de outros produtos. Por isso o vetor do `ork` mora aqui, no
7
+ * estado canonico do projeto, um arquivo por tenant, modelo e dimensao:
8
+ *
9
+ * <raiz canonica>/.orkastery/memoria/vetores/<tenant>/<modelo>-<dim>.json (0600, fora do git)
10
+ *
11
+ * O OrkMind continua a fonte da verdade; o indice e cache reconstruivel por `ork memory index`.
12
+ * A chave de cada vetor e (id, sha256 do content, modelo, dim): conteudo que mudou reembeda so
13
+ * aquela entrada, e arquivo de outro modelo, dimensao, tenant ou base nunca e misturado.
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.PRECO_USD_POR_TOKEN = exports.TIMEOUT_DO_LOTE_MS = exports.CARACTERES_POR_TOKEN = exports.TAMANHO_DO_LOTE = exports.CONTRATO_INDICE = void 0;
50
+ exports.dirDosIndices = dirDosIndices;
51
+ exports.arquivoDoIndice = arquivoDoIndice;
52
+ exports.sha256DoConteudo = sha256DoConteudo;
53
+ exports.impressaoDaBase = impressaoDaBase;
54
+ exports.codificarVetor = codificarVetor;
55
+ exports.decodificarVetor = decodificarVetor;
56
+ exports.lerIndice = lerIndice;
57
+ exports.serializarIndice = serializarIndice;
58
+ exports.gravarIndice = gravarIndice;
59
+ exports.universoDoTenant = universoDoTenant;
60
+ exports.conteudoRecusado = conteudoRecusado;
61
+ exports.tokensEstimados = tokensEstimados;
62
+ exports.dimDoModeloLocal = dimDoModeloLocal;
63
+ exports.codigoDeEmbedding = codigoDeEmbedding;
64
+ exports.espacoDoAlvo = espacoDoAlvo;
65
+ exports.indexar = indexar;
66
+ exports.vetoresCoerentes = vetoresCoerentes;
67
+ const fs = __importStar(require("node:fs"));
68
+ const os = __importStar(require("node:os"));
69
+ const path = __importStar(require("node:path"));
70
+ const node_crypto_1 = require("node:crypto");
71
+ const estado_thread_1 = require("./estado-thread");
72
+ const orkmind_1 = require("./orkmind");
73
+ const policies_1 = require("./policies");
74
+ exports.CONTRATO_INDICE = 'ork.indice-vetorial/v1';
75
+ /** D11: lote por chamada da ponte na indexacao. */
76
+ exports.TAMANHO_DO_LOTE = 16;
77
+ /** D11: estimativa conservadora para portugues; o provider da biblioteca descarta `usage`. */
78
+ exports.CARACTERES_POR_TOKEN = 3;
79
+ /** Indexar e trabalho de lote (madrugada), com prazo proprio; a consulta usa o prazo da ponte. */
80
+ exports.TIMEOUT_DO_LOTE_MS = 120_000;
81
+ /**
82
+ * D11: preco publico por token de entrada, conferido em 29/09/2026 com
83
+ * `curl -s https://openrouter.ai/api/v1/embeddings/models`. Estimativa: a fatura e o painel.
84
+ */
85
+ exports.PRECO_USD_POR_TOKEN = Object.freeze({
86
+ 'qwen/qwen3-embedding-8b': 0.00000001,
87
+ });
88
+ /** URL com credencial: o texto nunca vai ao provider. */
89
+ const URL_COM_CREDENCIAL = /\b[a-z][a-z0-9+.-]*:\/\/[^\s/:@]+:[^\s/@]+@/;
90
+ const seguro = (nome) => nome.replace(/\//g, '__').replace(/[^A-Za-z0-9_-]/g, '_');
91
+ function dirDosIndices(raiz, tenant) {
92
+ return path.join((0, estado_thread_1.raizDoEstado)(raiz), '.orkastery', 'memoria', 'vetores', seguro(tenant));
93
+ }
94
+ function arquivoDoIndice(raiz, tenant, modelo, dim) {
95
+ return path.join(dirDosIndices(raiz, tenant), `${seguro(modelo)}-${dim}.json`);
96
+ }
97
+ function sha256DoConteudo(conteudo) {
98
+ return (0, node_crypto_1.createHash)('sha256').update(conteudo, 'utf8').digest('hex');
99
+ }
100
+ /** Impressao da base: host, porta e banco, sem usuario nem senha. */
101
+ function impressaoDaBase(dsn) {
102
+ let alvo = '';
103
+ try {
104
+ const u = new URL(dsn);
105
+ alvo = `${u.hostname}:${u.port || '5432'}${u.pathname}`;
106
+ }
107
+ catch {
108
+ const campo = (k) => new RegExp(`(?:^|\\s)${k}=([^\\s]+)`).exec(dsn)?.[1] ?? '';
109
+ alvo = `${campo('host')}:${campo('port') || '5432'}/${campo('dbname')}`;
110
+ }
111
+ return (0, node_crypto_1.createHash)('sha256').update(alvo).digest('hex');
112
+ }
113
+ function codificarVetor(v) {
114
+ const buf = Buffer.alloc(v.length * 4);
115
+ v.forEach((x, i) => buf.writeFloatLE(x, i * 4));
116
+ return buf.toString('base64');
117
+ }
118
+ function decodificarVetor(b64, dim) {
119
+ const buf = Buffer.from(b64, 'base64');
120
+ if (buf.length !== dim * 4)
121
+ return null;
122
+ return Array.from({ length: dim }, (_, i) => buf.readFloatLE(i * 4));
123
+ }
124
+ /**
125
+ * Le o indice de (tenant, base, modelo, dim). Arquivo ausente, ilegivel ou de outro espaco
126
+ * vetorial volta vazio: reconstruir custa centesimos de centavo, misturar corrompe a busca.
127
+ */
128
+ function lerIndice(arquivo, esperado) {
129
+ const vazio = { contrato: exports.CONTRATO_INDICE, ...esperado, entradas: {} };
130
+ if (!fs.existsSync(arquivo))
131
+ return { indice: vazio, existia: false, outroEspaco: false };
132
+ try {
133
+ const o = JSON.parse(fs.readFileSync(arquivo, 'utf8'));
134
+ if (o.contrato !== exports.CONTRATO_INDICE || o.tenant !== esperado.tenant || o.base !== esperado.base ||
135
+ o.modelo !== esperado.modelo || o.dim !== esperado.dim || !o.entradas || typeof o.entradas !== 'object') {
136
+ return { indice: vazio, existia: true, outroEspaco: true };
137
+ }
138
+ const entradas = {};
139
+ for (const [id, e] of Object.entries(o.entradas)) {
140
+ if (e && typeof e.sha256 === 'string' && typeof e.colecao === 'string' && typeof e.vetor === 'string' &&
141
+ decodificarVetor(e.vetor, esperado.dim))
142
+ entradas[id] = e;
143
+ }
144
+ return { indice: { ...vazio, entradas }, existia: true, outroEspaco: false };
145
+ }
146
+ catch {
147
+ return { indice: vazio, existia: true, outroEspaco: true };
148
+ }
149
+ }
150
+ /** Serializacao estavel: mesma memoria, mesmos bytes (idempotencia provada por comparacao). */
151
+ function serializarIndice(indice) {
152
+ const entradas = Object.fromEntries(Object.keys(indice.entradas).sort().map(id => [id, {
153
+ colecao: indice.entradas[id].colecao, sha256: indice.entradas[id].sha256, vetor: indice.entradas[id].vetor
154
+ }]));
155
+ return JSON.stringify({ contrato: indice.contrato, tenant: indice.tenant, base: indice.base,
156
+ modelo: indice.modelo, dim: indice.dim, entradas }, null, 1) + '\n';
157
+ }
158
+ /** Escrita atomica, pasta 0700 e arquivo 0600; so grava quando os bytes mudam. */
159
+ function gravarIndice(arquivo, indice) {
160
+ const bytes = serializarIndice(indice);
161
+ if (fs.existsSync(arquivo) && fs.readFileSync(arquivo, 'utf8') === bytes)
162
+ return false;
163
+ const dir = path.dirname(arquivo);
164
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
165
+ fs.chmodSync(dir, 0o700);
166
+ const tmp = `${arquivo}.${process.pid}.tmp`;
167
+ fs.writeFileSync(tmp, bytes, { mode: 0o600 });
168
+ fs.renameSync(tmp, arquivo);
169
+ fs.chmodSync(arquivo, 0o600);
170
+ return true;
171
+ }
172
+ /**
173
+ * Universo do tenant: o export governado das colecoes do ork (filtro de injecao e visibilidade
174
+ * da biblioteca), com checagem EXPLICITA do tenant antes de qualquer texto ir ao embed.
175
+ */
176
+ function universoDoTenant(fonte, tenant, colecoes = orkmind_1.COLECOES_DO_ORK) {
177
+ return colecoes.flatMap(c => fonte.buscar({ collection: c, tags: { project: [tenant] } })
178
+ .filter(e => e.collection === c && (e.tags.project ?? []).includes(tenant)))
179
+ .sort((a, b) => a.collection.localeCompare(b.collection) || a.id.localeCompare(b.id));
180
+ }
181
+ /** Conteudo que nunca vai ao provider: padrao de segredo da policy ou URL com credencial. */
182
+ function conteudoRecusado(conteudo) {
183
+ return (0, policies_1.procurarSegredos)(conteudo).length > 0 || URL_COM_CREDENCIAL.test(conteudo);
184
+ }
185
+ function tokensEstimados(conteudo) {
186
+ return Math.ceil(conteudo.length / exports.CARACTERES_POR_TOKEN);
187
+ }
188
+ /**
189
+ * Dimensao nativa de um modelo local, lida do cache do Hugging Face sem rede e sem Python.
190
+ * null quando o modelo nao esta no cache (a busca cai para FTS com `embeddings.local-ausente`).
191
+ */
192
+ function dimDoModeloLocal(modelo, env = process.env) {
193
+ if (!modelo || !orkmind_1.MODELO_DE_EMBEDDING.test(modelo))
194
+ return null;
195
+ const hub = env.HF_HUB_CACHE || path.join(env.HF_HOME || path.join(env.HOME || os.homedir(), '.cache', 'huggingface'), 'hub');
196
+ const repo = path.join(hub, `models--${modelo.replace('/', '--')}`);
197
+ try {
198
+ const ref = fs.readFileSync(path.join(repo, 'refs', 'main'), 'utf8').trim();
199
+ if (!/^[0-9a-f]{40}$/.test(ref))
200
+ return null;
201
+ const config = JSON.parse(fs.readFileSync(path.join(repo, 'snapshots', ref, 'config.json'), 'utf8'));
202
+ const dim = Number(config.hidden_size ?? config.d_model ?? config.dim);
203
+ return Number.isInteger(dim) && dim >= 32 && dim <= 4096 ? dim : null;
204
+ }
205
+ catch {
206
+ return null;
207
+ }
208
+ }
209
+ function codigoDeEmbedding(erro) {
210
+ const m = erro instanceof Error ? erro.message : '';
211
+ const tipado = /^embeddings\.[a-z-]+/.exec(m)?.[0];
212
+ if (m === 'memory.transport.timeout')
213
+ return 'embeddings.timeout';
214
+ if (m.startsWith('memory.transport.secret'))
215
+ return 'embeddings.conteudo-recusado';
216
+ return tipado ?? 'embeddings.provider-indisponivel';
217
+ }
218
+ /** O par (modelo, dim) de cada alvo, ou o motivo tipado de nao haver. */
219
+ function espacoDoAlvo(config, alvo, env = process.env) {
220
+ if (config.provider === 'none')
221
+ return { motivo: 'embeddings.nao-configurado', detalhe: 'memory.embedding.provider none' };
222
+ if (alvo === 'primario')
223
+ return { modelo: config.model, dim: config.dim };
224
+ if (!config.fallback_model)
225
+ return { motivo: 'embeddings.nao-configurado', detalhe: 'memory.embedding.fallback_model vazio' };
226
+ const dim = dimDoModeloLocal(config.fallback_model, env);
227
+ if (dim === null)
228
+ return { motivo: 'embeddings.local-ausente', detalhe: `${config.fallback_model} ausente do cache local do Hugging Face` };
229
+ return { modelo: config.fallback_model, dim };
230
+ }
231
+ /**
232
+ * `ork memory index`: idempotente, com o teto de tokens conferido ANTES da rede.
233
+ *
234
+ * Pendentes sao as entradas do universo sem vetor coerente; removidos, as do indice que sairam
235
+ * do tenant; fora do limite e recusados nunca vao ao provider. Falha no meio preserva os lotes
236
+ * que ja voltaram, porque cada vetor gravado e coerente por si.
237
+ */
238
+ function indexar(o) {
239
+ const espaco = espacoDoAlvo(o.config, o.alvo, o.env);
240
+ const universo = o.universo.filter(e => (e.tags.project ?? []).includes(o.tenant));
241
+ const foraDoLimite = universo.filter(e => e.content.length > orkmind_1.EMBED_MAX_CARACTERES);
242
+ const recusados = universo.filter(e => e.content.length <= orkmind_1.EMBED_MAX_CARACTERES && conteudoRecusado(e.content));
243
+ const indexaveis = universo.filter(e => e.content.length <= orkmind_1.EMBED_MAX_CARACTERES && !conteudoRecusado(e.content) && e.content.trim());
244
+ const base = { alvo: o.alvo, modelo: null, dim: null, arquivo: null, dryRun: o.dryRun,
245
+ universo: universo.length, coerentes: 0, embedados: 0, reescritos: 0, removidos: 0, recusados: recusados.length,
246
+ foraDoLimite: foraDoLimite.length, truncados: 0, tokensEstimados: 0, custoEstimadoUsd: 0, chamadasAoProvider: 0, motivo: null, detalhe: '' };
247
+ if ('motivo' in espaco) {
248
+ const tokens = indexaveis.reduce((t, e) => t + tokensEstimados(e.content), 0);
249
+ return { ...base, tokensEstimados: tokens, motivo: espaco.motivo, detalhe: espaco.detalhe };
250
+ }
251
+ const arquivo = arquivoDoIndice(o.raiz, o.tenant, espaco.modelo, espaco.dim);
252
+ const { indice } = lerIndice(arquivo, { tenant: o.tenant, base: impressaoDaBase(o.dsn), modelo: espaco.modelo, dim: espaco.dim });
253
+ const ids = new Set(indexaveis.map(e => e.id));
254
+ const coerente = (e) => indice.entradas[e.id]?.sha256 === sha256DoConteudo(e.content);
255
+ const pendentes = indexaveis.filter(e => !coerente(e));
256
+ const removidos = Object.keys(indice.entradas).filter(id => !ids.has(id));
257
+ const tokens = pendentes.reduce((t, e) => t + tokensEstimados(e.content), 0);
258
+ const preco = o.alvo === 'fallback' ? 0 : exports.PRECO_USD_POR_TOKEN[espaco.modelo];
259
+ const r = { ...base, modelo: espaco.modelo, dim: espaco.dim,
260
+ arquivo: path.relative((0, estado_thread_1.raizDoEstado)(o.raiz), arquivo).split(path.sep).join('/'),
261
+ coerentes: indexaveis.length - pendentes.length, removidos: removidos.length, tokensEstimados: tokens,
262
+ custoEstimadoUsd: preco === undefined ? null : tokens * preco,
263
+ detalhe: preco === undefined ? `preco de ${espaco.modelo} fora da tabela datada: custo nao estimado` : '' };
264
+ if (o.dryRun)
265
+ return r;
266
+ if (o.alvo === 'primario' && !o.chavePresente) {
267
+ return { ...r, motivo: 'embeddings.chave-ausente', detalhe: o.chaveRecusada
268
+ ? 'a variavel declarada em memory.embedding.api_key_env tem valor recusado (parece URL, DSN ou texto com espaco; nunca impresso)'
269
+ : 'a variavel declarada em memory.embedding.api_key_env nao esta no ambiente' };
270
+ }
271
+ // D11: o teto de dinheiro vale antes de qualquer chamada; o fallback local nao cobra.
272
+ if (o.alvo === 'primario' && tokens > o.config.max_tokens_por_execucao) {
273
+ return { ...r, motivo: 'embeddings.orcamento-excedido',
274
+ detalhe: `${tokens} tokens estimados acima do teto de ${o.config.max_tokens_por_execucao} por execucao` };
275
+ }
276
+ if (!o.embeddar)
277
+ return { ...r, motivo: 'embeddings.provider-indisponivel', detalhe: 'transporte de embedding ausente' };
278
+ for (const id of removidos)
279
+ delete indice.entradas[id];
280
+ let motivo = null;
281
+ for (let i = 0; i < pendentes.length && !motivo; i += exports.TAMANHO_DO_LOTE) {
282
+ const lote = pendentes.slice(i, i + exports.TAMANHO_DO_LOTE);
283
+ r.chamadasAoProvider += 1;
284
+ try {
285
+ const resposta = o.embeddar({ papel: 'documento', alvo: o.alvo, modelo: espaco.modelo, dim: espaco.dim,
286
+ textos: lote.map(e => e.content) }, { timeoutMs: exports.TIMEOUT_DO_LOTE_MS });
287
+ lote.forEach((e, j) => {
288
+ if (indice.entradas[e.id])
289
+ r.reescritos += 1;
290
+ indice.entradas[e.id] = { colecao: e.collection, sha256: sha256DoConteudo(e.content), vetor: codificarVetor(resposta.vetores[j]) };
291
+ r.embedados += 1;
292
+ });
293
+ r.truncados += resposta.truncados?.length ?? 0;
294
+ }
295
+ catch (erro) {
296
+ motivo = codigoDeEmbedding(erro);
297
+ }
298
+ }
299
+ gravarIndice(arquivo, indice);
300
+ r.coerentes = indexaveis.filter(coerente).length;
301
+ if (motivo)
302
+ return { ...r, motivo, detalhe: `indexacao interrompida depois de ${r.embedados} vetor(es); os lotes concluidos ficaram gravados` };
303
+ return r;
304
+ }
305
+ /** Vetores coerentes de um indice para o universo informado: a base da busca e da cobertura. */
306
+ function vetoresCoerentes(indice, universo) {
307
+ const saida = new Map();
308
+ for (const e of universo) {
309
+ const item = indice.entradas[e.id];
310
+ if (!item || item.sha256 !== sha256DoConteudo(e.content))
311
+ continue;
312
+ const v = decodificarVetor(item.vetor, indice.dim);
313
+ if (v)
314
+ saida.set(e.id, v);
315
+ }
316
+ return saida;
317
+ }
package/dist/init.js CHANGED
@@ -156,6 +156,10 @@ owner:
156
156
  # fuso do dono (nome IANA): todo horario mostrado a pessoas usa este fuso.
157
157
  # Ausente: fuso do sistema. Exemplo:
158
158
  # timezone: "${horario_1.FUSO_DE_BRASILIA}"
159
+ # Preferências: ork onboarding set maestro --conteudo '{"owner":{"experience":true}}'
160
+ # language: pt-BR # ausente: locale do sistema
161
+ # depth: curta # curta | detalhada
162
+ # experience: true # false desativa o pacote na próxima instalação do adaptador
159
163
 
160
164
  board:
161
165
  adapter: hermes-kanban
@@ -227,6 +231,15 @@ memory:
227
231
  database_url_env: ""
228
232
  cli: orkmind
229
233
  timeout_ms: 15000
234
+ # busca por significado (ork memory search --texto): sem o bloco, provider none (desligada).
235
+ # api_key_env recebe o NOME da variavel com a chave dedicada, nunca o valor.
236
+ # embedding:
237
+ # provider: "none" # none | openrouter
238
+ # model: "qwen/qwen3-embedding-8b"
239
+ # dim: 1024
240
+ # api_key_env: "ORKASTERY_EMBEDDING_API_KEY"
241
+ # fallback_model: "" # modelo local offline, ex.: intfloat/multilingual-e5-small
242
+ # max_tokens_por_execucao: 1000000
230
243
 
231
244
  audit:
232
245
  # governanca de custo dos auditores periodicos (bloco B5)
@@ -10,7 +10,7 @@ exports.TESTES_DE_INTEGRACAO_LOCAL = void 0;
10
10
  * daqui, e o script le o mesmo modulo ja compilado em `dist/` (o `test:ci` compila antes).
11
11
  */
12
12
  exports.TESTES_DE_INTEGRACAO_LOCAL = new Set([
13
- 'codex-controller-sensor.test.js', 'consulta-restrita-nativa.test.js', 'decision-identity.test.js',
13
+ 'codex-controller-sensor.test.js', 'consulta-restrita-nativa.test.js', 'decision-identity.test.js', 'embedding-ponte.test.js',
14
14
  'mcp-git.test.js', 'mcp-server.test.js', 'mcp-ship.test.js', 'mcp-verify.test.js',
15
15
  'memory-native-preparation.test.js', 'memory-native-schema.test.js', 'memory-prospective.test.js',
16
16
  'memory-publication-profile.test.js', 'native-fixture.test.js', 'orkmind-transport.test.js', 'verify-sandbox.test.js',