auroq-os 2.5.9 → 2.5.11
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/.auroq-core/core-config.yaml +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +5 -5
- package/bin/auroq-os.js +59 -15
- package/installer/README.md +2 -3
- package/installer/install.ps1 +2 -2
- package/installer/install.sh +2 -2
- package/lib/telemetry.mjs +4 -1
- package/package.json +1 -1
- package/scripts/assert-mcp-pin.mjs +10 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## 2.5.11 — 2026-09-21
|
|
2
|
+
|
|
3
|
+
### O diagnostico passa a dizer o que achou (EMB-050)
|
|
4
|
+
|
|
5
|
+
- Sair com 1 no `doctor` nao e mais `INSTALL_FAILED`: agora e `DOCTOR_FINDINGS`. Pendencia encontrada e o diagnostico trabalhando, nao instalacao quebrada — na janela de 20/09 isso gerou 3 alarmes de gravidade maxima para zero instalacoes quebradas.
|
|
6
|
+
- O `doctor` grava o resultado em `~/.auroq/install.log`: `pendencias=N etiqueta,etiqueta` quando acha algo e `ok` quando fecha limpo. As etiquetas sao vocabulario fechado (`arquivos-faltando`, `motor-fora-do-perfil`, `sem-login`, ...) e nunca levam caminho, e-mail, token nem nome de maquina. O suporte pede uma linha: `cat ~/.auroq/install.log`.
|
|
7
|
+
- Registro MCP passa a `arcane-mcp@0.6.1` (publicado no npm em 21/09/2026), que conhece o codigo novo: os dois clientes compartilham a mesma fila local e qualquer um dos dois a envia, entao a lista de codigos tem que ser a mesma nos dois e no servidor. Feche e abra o Claude Code e o Codex depois da manutencao.
|
|
8
|
+
- Instaladores oficiais continuam fixando 2.5.10; promover a versao que instalacoes NOVAS recebem segue sendo ato explicito.
|
|
9
|
+
|
|
10
|
+
## 2.5.10 — 2026-09-19
|
|
11
|
+
|
|
12
|
+
### Conteudo ao vivo passa a usar o cliente 0.6.0
|
|
13
|
+
|
|
14
|
+
- `arcane-mcp@0.6.0` foi publicado no npm em 19/09/2026 e virou o registro oficial de Claude Code e Codex.
|
|
15
|
+
- Instalacao, manutencao, `register-mcp` e `doctor` trocam qualquer pin antigo pelo vigente — inclusive quem ficou com o `0.6.0` fantasma das 2.5.4/2.5.5, que agora resolve de verdade.
|
|
16
|
+
- Sai o remendo que tratava `0.6.0` como versao morta. A protecao contra pin inexistente continua no gate de publicacao, que agora exige do `npm view` a versao exata do pin.
|
|
17
|
+
|
|
1
18
|
## 2.5.9 — 2026-09-14
|
|
2
19
|
|
|
3
20
|
### Historico duravel do trabalho Arcane
|
package/README.md
CHANGED
|
@@ -230,12 +230,12 @@ agents/ → Seu exercito (companion, workers, minds, squads)
|
|
|
230
230
|
|
|
231
231
|
## Observabilidade do motor (candidato 2.5.2)
|
|
232
232
|
|
|
233
|
-
Apos publicacao, `npx -y auroq-os@2.5.
|
|
234
|
-
manutencao/diagnostico. `npx -y auroq-os@2.5.
|
|
233
|
+
Apos publicacao, `npx -y auroq-os@2.5.11 doctor` mostra a fila local segura e os comandos pinados de
|
|
234
|
+
manutencao/diagnostico. `npx -y auroq-os@2.5.11 manutencao` preserva o caminho existente
|
|
235
235
|
de consentimento legado, studentFiles, customizacoes e dados do negocio. Nao ha
|
|
236
|
-
migracao forcada. O registro MCP aponta para `arcane-mcp@0.
|
|
237
|
-
|
|
238
|
-
Os instaladores oficiais
|
|
236
|
+
migracao forcada. O registro MCP aponta para `arcane-mcp@0.6.1`, publicado no npm em
|
|
237
|
+
21/09/2026; `npm run release:verify` recusa publicar com um pin que o npm nao resolva.
|
|
238
|
+
Os instaladores oficiais seguem em 2.5.10; promover pra 2.5.11 e ato explicito, depois da publicacao e da verificacao do tarball.
|
|
239
239
|
|
|
240
240
|
O CLI inicia captura antes das dependencias pesadas e registra resultado ao sair.
|
|
241
241
|
Eventos com identidade ja existente podem seguir pela rota autenticada na proxima
|
package/bin/auroq-os.js
CHANGED
|
@@ -20,7 +20,10 @@ async function observedMain() {
|
|
|
20
20
|
const record = (outcome, error_code) => telemetry.enqueue(owner,{endpoint:'lifecycle',stage,outcome,error_code});
|
|
21
21
|
telemetry.setHost('auroq-os');telemetry.importInstallerSpool();record('started');
|
|
22
22
|
let importing = true;
|
|
23
|
-
|
|
23
|
+
// Sair com 1 no `doctor` e o diagnostico fazendo o trabalho dele, nao a instalacao quebrando:
|
|
24
|
+
// `DOCTOR_FINDINGS` = achou pendencia pra resolver. Chamar isso de INSTALL_FAILED gerava alarme
|
|
25
|
+
// de gravidade maxima pra aluno com o caminho inteiro de pe (Marinei e Alessandra, 20/09).
|
|
26
|
+
process.once('exit',code=>record(code===0?'ok':'error',code===0?null:importing?'BOOTSTRAP_IMPORT':stage==='update'?'UPDATE_FAILED':stage==='doctor'?'DOCTOR_FINDINGS':'INSTALL_FAILED'));
|
|
24
27
|
process.once('uncaughtException',()=>{console.error('[auroq-os] RUNTIME_FAILURE');process.exit(1);});
|
|
25
28
|
process.once('unhandledRejection',()=>{console.error('[auroq-os] RUNTIME_FAILURE');process.exit(1);});
|
|
26
29
|
const cred = credentials.load();await telemetry.flush(cred?.user?.id,cred?.access_token);
|
|
@@ -28,7 +31,7 @@ async function observedMain() {
|
|
|
28
31
|
telemetry.runtimeReady=()=>{importing=false;};
|
|
29
32
|
runRuntime(telemetry);
|
|
30
33
|
} catch {
|
|
31
|
-
console.error('[auroq-os] '+(importing?'BOOTSTRAP_IMPORT':'RUNTIME_FAILURE')+'. Rode: npx -y auroq-os@2.5.
|
|
34
|
+
console.error('[auroq-os] '+(importing?'BOOTSTRAP_IMPORT':'RUNTIME_FAILURE')+'. Rode: npx -y auroq-os@2.5.11 doctor');
|
|
32
35
|
process.exitCode=1;
|
|
33
36
|
}
|
|
34
37
|
}
|
|
@@ -214,13 +217,45 @@ function registrarInstallLog(evento, detalhe = '') {
|
|
|
214
217
|
const dir = path.join(require('os').homedir(), '.auroq');
|
|
215
218
|
fs.ensureDirSync(dir);
|
|
216
219
|
const quando = new Date().toISOString().replace(/\.\d+Z$/, 'Z');
|
|
217
|
-
const limpo = String(detalhe).replace(/[^\w
|
|
220
|
+
const limpo = String(detalhe).replace(/[^\w ,.:=+/\\-]/g, '');
|
|
218
221
|
fs.appendFileSync(path.join(dir, 'install.log'), `${quando}\t${evento}\t${limpo}\n`);
|
|
219
222
|
} catch {
|
|
220
223
|
/* registro e conveniencia pro suporte */
|
|
221
224
|
}
|
|
222
225
|
}
|
|
223
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Etiqueta curta e FIXA pra cada pendencia que o `doctor` lista (EMB-050).
|
|
229
|
+
*
|
|
230
|
+
* O suporte precisa saber "falhou no que", nao so "falhou": a lista do doctor morria na tela do
|
|
231
|
+
* aluno e o plantao ficava adivinhando (da Alessandra nunca soubemos qual item era). A etiqueta e
|
|
232
|
+
* vocabulario fechado de proposito — nunca caminho, e-mail, token, nome de maquina nem o texto da
|
|
233
|
+
* pendencia. O casamento e por trecho estavel da mensagem; o teste `doctor-recibo` reprova qualquer
|
|
234
|
+
* pendencia nova que caia em `outro`.
|
|
235
|
+
*/
|
|
236
|
+
const ETIQUETAS_DOCTOR = [
|
|
237
|
+
['repor o que falta', 'arquivos-faltando'],
|
|
238
|
+
['sem tirar nada seu', 'synapse-nao-registrado'],
|
|
239
|
+
['Synapse antigo', 'synapse-antigo'],
|
|
240
|
+
['no Windows, install.ps1', 'motor-ausente'],
|
|
241
|
+
['FECHE e abra', 'motor-fora-do-perfil'],
|
|
242
|
+
['2 minutos de espera', 'mcp-timeout-curto'],
|
|
243
|
+
['com o tempo certo', 'codex-timeout-curto'],
|
|
244
|
+
['mais tempo ao Codex', 'arranque-lento'],
|
|
245
|
+
['reescreve o registro)', 'mcp-nao-registrado'],
|
|
246
|
+
['register-mcp na pasta. Depois', 'mcp-pin-antigo'],
|
|
247
|
+
['arcane-mcp login', 'sem-login'],
|
|
248
|
+
['fora do ar', 'servidor-fora'],
|
|
249
|
+
['Confira sua internet', 'servidor-fora'],
|
|
250
|
+
['whoami', 'mcp-nao-abre'],
|
|
251
|
+
['tela INTEIRA', 'codex-sem-conteudo'],
|
|
252
|
+
];
|
|
253
|
+
function rotulo(pendencia) {
|
|
254
|
+
const texto = String(pendencia || '');
|
|
255
|
+
for (const [marca, etiqueta] of ETIQUETAS_DOCTOR) if (texto.includes(marca)) return etiqueta;
|
|
256
|
+
return 'outro';
|
|
257
|
+
}
|
|
258
|
+
|
|
224
259
|
/**
|
|
225
260
|
* Identificador curto e nao reversivel da maquina — so pro suporte casar dois
|
|
226
261
|
* registros do mesmo computador. Nao sai da maquina e nao contem nome nem e-mail.
|
|
@@ -363,14 +398,14 @@ async function runDoctor(targetDir) {
|
|
|
363
398
|
pin = json?.mcpServers?.arcane?.args?.find(a => String(a).startsWith('arcane-mcp@')) || null;
|
|
364
399
|
} catch { /* arquivo corrompido cai no erro abaixo */ }
|
|
365
400
|
}
|
|
366
|
-
if (pin &&
|
|
367
|
-
const
|
|
401
|
+
if (pin && pin !== ARCANE_MCP_PIN) {
|
|
402
|
+
const pinAntigo = pin;
|
|
368
403
|
try {
|
|
369
404
|
await writeArcaneMcpConfig(targetDir);
|
|
370
405
|
pin = ARCANE_MCP_PIN;
|
|
371
|
-
warn(`O registro apontava pra ${
|
|
406
|
+
warn(`O registro apontava pra ${pinAntigo}, versao antiga do conteudo ao vivo. Atualizei pra ${pin}. Feche e abra o Claude Code e o Codex.`);
|
|
372
407
|
} catch (e) {
|
|
373
|
-
error(`O registro aponta pra ${
|
|
408
|
+
error(`O registro aponta pra ${pinAntigo}, versao antiga do conteudo ao vivo, e nao consegui atualizar (${e.code || e.message})`);
|
|
374
409
|
problemas.push('Rode: npx auroq-os@latest register-mcp na pasta. Depois feche e abra o Claude Code e o Codex.');
|
|
375
410
|
}
|
|
376
411
|
}
|
|
@@ -503,12 +538,22 @@ async function runDoctor(targetDir) {
|
|
|
503
538
|
}
|
|
504
539
|
|
|
505
540
|
log('');
|
|
541
|
+
// Recibo duravel pro suporte, inclusive quando fechou limpo: sem o historico completo o plantao
|
|
542
|
+
// nao sabe se a pendencia de ontem foi resolvida. Conveniencia — nunca pode derrubar o doctor,
|
|
543
|
+
// por isso montar o texto tambem fica DENTRO do try.
|
|
544
|
+
const recibo = pendencias => {
|
|
545
|
+
try {
|
|
546
|
+
registrarInstallLog('doctor', pendencias.length ? `pendencias=${pendencias.length} ${pendencias.map(p => rotulo(p)).join(',')}` : 'ok');
|
|
547
|
+
} catch { /* recibo e conveniencia pro suporte */ }
|
|
548
|
+
};
|
|
506
549
|
if (problemas.length === 0) {
|
|
507
550
|
success('Tudo certo. Pode chamar o Companion.');
|
|
551
|
+
recibo(problemas);
|
|
508
552
|
return 0;
|
|
509
553
|
}
|
|
510
554
|
error(`${problemas.length} coisa(s) pra resolver:`);
|
|
511
555
|
for (const p of problemas) log(` ${DIM}- ${p}${RESET}`);
|
|
556
|
+
recibo(problemas);
|
|
512
557
|
log('');
|
|
513
558
|
log(`${DIM}Se travar, chame o suporte: 11 93621-4486${RESET}`);
|
|
514
559
|
return 1;
|
|
@@ -521,11 +566,10 @@ async function runDoctor(targetDir) {
|
|
|
521
566
|
// (rede domestica + antivirus) a aluna viu timeout em todas as que fez. Por isso:
|
|
522
567
|
// (1) o registro do Codex pede mais tempo, (2) instalacao/atualizacao ja baixam o
|
|
523
568
|
// pacote, (3) o doctor mede o arranque de verdade em vez de so olhar o registro.
|
|
524
|
-
|
|
525
|
-
//
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
}
|
|
569
|
+
// 2.5.4/2.5.5 pinaram uma versao que ainda nao estava no npm e o MCP fechava a conexao.
|
|
570
|
+
// Por isso `scripts/assert-mcp-pin.mjs` (release:verify/prepublishOnly) recusa publicar
|
|
571
|
+
// com um pin que o `npm view` nao resolva exatamente. Trocar o pin aqui exige o pacote ja publicado.
|
|
572
|
+
const ARCANE_MCP_PIN = 'arcane-mcp@0.6.1';
|
|
529
573
|
const CODEX_MCP_STARTUP_SEC = 120;
|
|
530
574
|
// O Claude Code tambem desistia aos 30s (MCP_TIMEOUT) e o aluno via CONNECT_TIMEOUT com o
|
|
531
575
|
// servidor no ar e nenhum pedido chegando nele (11/09, EMB-041). Ele le o tempo do `env` das
|
|
@@ -578,7 +622,7 @@ function blocoCodexArcane(pin, opcoes) {
|
|
|
578
622
|
}
|
|
579
623
|
|
|
580
624
|
// Baixa o pacote do conteudo ao vivo com o MESMO nome que o registro usa (o cache do
|
|
581
|
-
// npx e por nome+versao: `arcane-mcp` e `arcane-mcp@0.
|
|
625
|
+
// npx e por nome+versao: `arcane-mcp` e `arcane-mcp@0.6.1` sao caches diferentes).
|
|
582
626
|
// `npx` no Windows e um .cmd: sem shell o Node recusa (EINVAL) e com `shell: true` o Node 24
|
|
583
627
|
// imprime um DeprecationWarning na tela do aluno (DEP0190). Chamar o cmd.exe direto, sem shell.
|
|
584
628
|
function comandoNpx(args) {
|
|
@@ -1804,7 +1848,7 @@ if (['init', 'install', 'update'].includes(command)) {
|
|
|
1804
1848
|
error('Comando aposentado. Nada foi instalado ou alterado.');
|
|
1805
1849
|
error('Primeira instalacao: https://arcane.arka.education/auroq');
|
|
1806
1850
|
error('No negocio existente, peca ao Ops: manutencao do motor. Conteudo chega pelo MCP.');
|
|
1807
|
-
error('Diagnostico: npx -y auroq-os@2.5.
|
|
1851
|
+
error('Diagnostico: npx -y auroq-os@2.5.11 doctor. Manutencao: npx -y auroq-os@2.5.11 manutencao.');
|
|
1808
1852
|
process.exitCode = 1;
|
|
1809
1853
|
} else if (command === 'instalar' || command === 'manutencao') {
|
|
1810
1854
|
// `--pasta <nome>`: o instalador manda o CLI criar e entrar na pasta do negocio,
|
|
@@ -1931,6 +1975,6 @@ if (['init', 'install', 'update'].includes(command)) {
|
|
|
1931
1975
|
log('');
|
|
1932
1976
|
}
|
|
1933
1977
|
|
|
1934
|
-
if (process.env.AUROQ_EXPORTA_INTERNOS === '1') module.exports = { blocoCodexArcane, envCodexArcane, lerBlocoArcane, lerEnvDoBloco, limparArcaneDoGlobal, envComoCodex, argumentosCodexSmoke, avaliarEventosCodex,
|
|
1978
|
+
if (process.env.AUROQ_EXPORTA_INTERNOS === '1') module.exports = { blocoCodexArcane, envCodexArcane, lerBlocoArcane, lerEnvDoBloco, limparArcaneDoGlobal, envComoCodex, argumentosCodexSmoke, avaliarEventosCodex, rotulo, ARCANE_MCP_PIN };
|
|
1935
1979
|
|
|
1936
1980
|
}
|
package/installer/README.md
CHANGED
|
@@ -114,8 +114,7 @@ Limites: 200 slots por formato, sem captura antes
|
|
|
114
114
|
do download do proprio script, sem garantia de reconexao/adocao. Fonte oficial segue
|
|
115
115
|
neste diretorio; `plataforma-arcane/npm run sync:installer` sincroniza as duas copias.
|
|
116
116
|
|
|
117
|
-
Pins oficiais usam `auroq-os@2.5.
|
|
118
|
-
`arcane-mcp@0.
|
|
119
|
-
Candidato cliente 0.6.0 segue separado ate concluir os gates. O runtime Windows
|
|
117
|
+
Pins oficiais usam `auroq-os@2.5.10`, que registra o cliente publicado
|
|
118
|
+
`arcane-mcp@0.6.0` (no npm desde 19/09/2026). O runtime Windows
|
|
120
119
|
faz fail-closed ate dispor de ACL/no-follow seguros; spool PowerShell permanece local.
|
|
121
120
|
Execucao Linux de Bash/Perl nao valida macOS nem Windows/PowerShell 5.1.
|
package/installer/install.ps1
CHANGED
|
@@ -589,7 +589,7 @@ function Invoke-AuroqLogin {
|
|
|
589
589
|
# sucesso. Usado como pergunta de sim/nao, ele dizia "voce ja estava logado"
|
|
590
590
|
# pra quem nunca logou, pulava o portao e deixava a conta sem acesso chegar ate
|
|
591
591
|
# a criacao da pasta.
|
|
592
|
-
& (Get-AuroqNpx) -y auroq-os@2.5.
|
|
592
|
+
& (Get-AuroqNpx) -y auroq-os@2.5.10 check-access
|
|
593
593
|
if ($LASTEXITCODE -ne 0) {
|
|
594
594
|
Write-AuroqLog 'login' 'recusado'
|
|
595
595
|
Write-Host ''
|
|
@@ -677,7 +677,7 @@ function Invoke-AuroqInit {
|
|
|
677
677
|
if ($env:AUROQ_INSTALL_DRY_RUN) { Write-AuroqOk 'Sistema - seria montado aqui'; return }
|
|
678
678
|
|
|
679
679
|
Set-Location $script:AuroqPastaAlvo
|
|
680
|
-
& (Get-AuroqNpx) -y auroq-os@2.5.
|
|
680
|
+
& (Get-AuroqNpx) -y auroq-os@2.5.10 instalar
|
|
681
681
|
if ($LASTEXITCODE -ne 0) {
|
|
682
682
|
Write-AuroqLog 'init' 'falhou'
|
|
683
683
|
Write-AuroqErro 'A montagem do sistema parou no meio.' 'Rode o mesmo comando de novo. Se repetir, mande pro suporte o arquivo install.log da pasta .auroq.'
|
package/installer/install.sh
CHANGED
|
@@ -219,9 +219,9 @@ auroq_tem_terminal() {
|
|
|
219
219
|
# recebem pedaco do script no lugar da resposta dele.
|
|
220
220
|
auroq_npx_aluno() {
|
|
221
221
|
if [ -t 0 ]; then
|
|
222
|
-
npx -y auroq-os@2.5.
|
|
222
|
+
npx -y auroq-os@2.5.10 "$@"
|
|
223
223
|
else
|
|
224
|
-
npx -y auroq-os@2.5.
|
|
224
|
+
npx -y auroq-os@2.5.10 "$@" < /dev/tty
|
|
225
225
|
fi
|
|
226
226
|
}
|
|
227
227
|
|
package/lib/telemetry.mjs
CHANGED
|
@@ -20,7 +20,10 @@ export function networkCode(e) {
|
|
|
20
20
|
}
|
|
21
21
|
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
22
22
|
const uuid = v => typeof v === 'string' && UUID.test(v) ? v : null;
|
|
23
|
-
|
|
23
|
+
// DOCTOR_FINDINGS: o doctor achou pendencia e saiu com 1 — diagnostico trabalhando, nao instalacao
|
|
24
|
+
// quebrada. Os dois clientes gravam no MESMO outbox e qualquer um faz o flush, entao a lista tem que
|
|
25
|
+
// ser a mesma nos dois (e no servidor): o que falta aqui vira null e apaga o alarme (EMB-050).
|
|
26
|
+
const ERRORS = new Set(['NETWORK_TLS','NETWORK_DNS','NETWORK_TIMEOUT','NETWORK_OTHER','AUTH_MISSING','AUTH_REFRESH','HTTP_ERROR','CLIENT_ERROR','BOOTSTRAP_IMPORT','RUNTIME_FAILURE','INSTALL_FAILED','UPDATE_FAILED','DOCTOR_FINDINGS']);
|
|
24
27
|
const STAGES = new Set(['startup','runtime','install','update','doctor','login','bootstrap','git','node','access','folder','framework']);
|
|
25
28
|
const tools = new Set(['catalogo_listar','squad_ativar','squad_passo','squad_conhecimento','forja_bundle','busca']);
|
|
26
29
|
const TTL = 7*86400000;
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Recusa publicar auroq-os pinando um arcane-mcp que o npm nao resolve.
|
|
4
|
-
* Foi assim que 2.5.4/2.5.5 sairam
|
|
4
|
+
* Foi assim que 2.5.4/2.5.5 sairam pinando uma versao inexistente (Connection closed no aluno).
|
|
5
|
+
* Nao basta o `npm view` responder algo: a versao devolvida tem que ser EXATAMENTE a do pin.
|
|
5
6
|
*/
|
|
6
7
|
import { execFileSync } from 'node:child_process';
|
|
7
8
|
import fs from 'node:fs';
|
|
@@ -20,12 +21,17 @@ if (!/^arcane-mcp@\d+\.\d+\.\d+$/.test(pin)) {
|
|
|
20
21
|
console.error(`assert-mcp-pin: pin invalido: ${pin}`);
|
|
21
22
|
process.exit(1);
|
|
22
23
|
}
|
|
24
|
+
const esperada = pin.split('@').pop();
|
|
25
|
+
let v;
|
|
23
26
|
try {
|
|
24
|
-
|
|
25
|
-
if (!v) throw new Error('vazio');
|
|
26
|
-
console.log(`assert-mcp-pin: ${pin} existe (${v})`);
|
|
27
|
+
v = execFileSync('npm', ['view', pin, 'version'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
|
|
27
28
|
} catch (e) {
|
|
28
29
|
const detalhe = e.stderr ? String(e.stderr).split('\n').find(Boolean) : e.message;
|
|
29
30
|
console.error(`assert-mcp-pin: ${pin} nao existe no npm. ${detalhe || ''}`.trim());
|
|
30
31
|
process.exit(1);
|
|
31
32
|
}
|
|
33
|
+
if (v !== esperada) {
|
|
34
|
+
console.error(`assert-mcp-pin: ${pin} resolveu para "${v || '(vazio)'}", nao para ${esperada}.`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
console.log(`assert-mcp-pin: ${pin} existe no npm e resolve exatamente para ${v}`);
|