auroq-os 2.3.7 → 2.4.1
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/README.md +22 -0
- package/bin/auroq-os.js +106 -11
- package/installer/README.md +102 -0
- package/installer/install.ps1 +515 -0
- package/installer/install.sh +553 -0
- package/lib/auth.js +14 -2
- package/lib/diagnostico.js +125 -0
- package/package.json +3 -2
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
# Auroq OS - instalador do Windows.
|
|
2
|
+
#
|
|
3
|
+
# irm https://arka.education/install.ps1 | iex
|
|
4
|
+
#
|
|
5
|
+
# Roda no PowerShell 5.1 (o que vem no Windows 10) sem privilegio elevado. A politica
|
|
6
|
+
# de execucao nao entra aqui: ela so afeta arquivo .ps1 salvo em disco, e este
|
|
7
|
+
# script roda em memoria. Exigir elevacao era resto da era npm.
|
|
8
|
+
#
|
|
9
|
+
# Ordem obrigatoria (PRD "Embarque em 2 passos" sec. 4.2):
|
|
10
|
+
# diagnostico -> Git -> motor -> login da mentoria -> pasta do negocio -> init
|
|
11
|
+
#
|
|
12
|
+
# O `init` e quem escreve o registro do conteudo ao vivo (ADR-7).
|
|
13
|
+
#
|
|
14
|
+
# Modo biblioteca (usado pelos testes): $env:AUROQ_INSTALL_LIB='1'; . install.ps1
|
|
15
|
+
# Modo ensaio (nao toca em nada): $env:AUROQ_INSTALL_DRY_RUN='1'
|
|
16
|
+
|
|
17
|
+
# TLS 1.2 antes de qualquer download - sem isto o Windows 10 antigo estoura em SSL.
|
|
18
|
+
# ATENCAO: este arquivo e ASCII PURO de proposito. Nao coloque acento, travessao
|
|
19
|
+
# nem simbolo aqui.
|
|
20
|
+
#
|
|
21
|
+
# O Windows PowerShell 5.1 (o que vem no Windows, e o que o aluno usa) le script
|
|
22
|
+
# sem BOM na codepage do sistema - Windows-1252 no Brasil. Cada caractere UTF-8
|
|
23
|
+
# de dois ou tres bytes vira lixo, e o parser morre com "Missing closing '}'"
|
|
24
|
+
# antes de executar UMA linha. Provado numa maquina Windows real: lido como
|
|
25
|
+
# Windows-1252 => 4 erros de sintaxe; lido como UTF-8 => nenhum.
|
|
26
|
+
#
|
|
27
|
+
# ASCII puro resolve os dois caminhos de uma vez: rodar o arquivo do disco e
|
|
28
|
+
# baixar por `irm ... | iex`, onde a decodificacao depende do que o servidor
|
|
29
|
+
# declara.
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
|
33
|
+
} catch {
|
|
34
|
+
# PowerShell 7 ja negocia TLS moderno sozinho
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
$AuroqSuporte = '11 93621-4486'
|
|
38
|
+
$AuroqNodeMin = 20
|
|
39
|
+
$AuroqBuildMin = 17763 # Windows 10 1809
|
|
40
|
+
$AuroqDiscoMinMb = 2048
|
|
41
|
+
|
|
42
|
+
function Get-AuroqHome {
|
|
43
|
+
if ($env:AUROQ_INSTALL_HOME) { return $env:AUROQ_INSTALL_HOME }
|
|
44
|
+
if ($env:USERPROFILE) { return $env:USERPROFILE }
|
|
45
|
+
return $HOME
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function Get-AuroqNodeDir {
|
|
49
|
+
$base = $env:LOCALAPPDATA
|
|
50
|
+
if (-not $base) { $base = Join-Path (Get-AuroqHome) 'AppData\Local' }
|
|
51
|
+
return (Join-Path $base 'Auroq\node')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# --- Fala com o aluno ---------------------------------------------------------
|
|
55
|
+
|
|
56
|
+
function Write-AuroqTitulo { param([string]$Texto) Write-Host ''; Write-Host " $Texto" -ForegroundColor Magenta; Write-Host '' }
|
|
57
|
+
function Write-AuroqPasso { param([string]$Texto) Write-Host ''; Write-Host " > $Texto" -ForegroundColor Cyan }
|
|
58
|
+
function Write-AuroqDiz { param([string]$Texto) Write-Host " $Texto" }
|
|
59
|
+
function Write-AuroqOk { param([string]$Texto) Write-Host " + $Texto" -ForegroundColor Green }
|
|
60
|
+
function Write-AuroqAviso { param([string]$Texto) Write-Host " ! $Texto" -ForegroundColor Yellow }
|
|
61
|
+
|
|
62
|
+
# Toda falha diz tres coisas: o que aconteceu, o que fazer agora e o suporte.
|
|
63
|
+
function Write-AuroqErro {
|
|
64
|
+
param([string]$Aconteceu = 'Algo deu errado.', [string]$OqueFazer = 'Rode o mesmo comando de novo.')
|
|
65
|
+
Write-Host ''
|
|
66
|
+
Write-Host " Parou aqui: $Aconteceu" -ForegroundColor Red
|
|
67
|
+
Write-Host ''
|
|
68
|
+
Write-Host " O que fazer agora: $OqueFazer" -ForegroundColor Cyan
|
|
69
|
+
Write-Host ''
|
|
70
|
+
Write-Host " Se continuar travado, chame o suporte: $AuroqSuporte" -ForegroundColor DarkGray
|
|
71
|
+
Write-Host ''
|
|
72
|
+
Write-AuroqLog 'erro' $Aconteceu
|
|
73
|
+
exit 1
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# --- Registro pro suporte (sec. 5.7) ----------------------------------------------
|
|
77
|
+
# Uma linha por evento. Nunca entra senha, token ou e-mail.
|
|
78
|
+
|
|
79
|
+
function Write-AuroqLog {
|
|
80
|
+
param([string]$Evento = '', [string]$Detalhe = '')
|
|
81
|
+
if ($env:AUROQ_INSTALL_DRY_RUN) { return }
|
|
82
|
+
try {
|
|
83
|
+
$dir = Join-Path (Get-AuroqHome) '.auroq'
|
|
84
|
+
if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
|
85
|
+
$quando = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
|
|
86
|
+
Add-Content -Path (Join-Path $dir 'install.log') -Value "$quando`t$Evento`t$Detalhe" -Encoding UTF8
|
|
87
|
+
} catch {
|
|
88
|
+
# registro e conveniencia pro suporte; nunca derruba a instalacao
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# --- Decisoes puras (testadas uma a uma) --------------------------------------
|
|
93
|
+
|
|
94
|
+
# So letras minusculas, numeros e hifen. -cmatch porque o -match do PowerShell
|
|
95
|
+
# ignora maiuscula por padrao e deixaria passar "MinhaEmpresa".
|
|
96
|
+
function Test-AuroqPasta {
|
|
97
|
+
param([string]$Nome = '')
|
|
98
|
+
if ([string]::IsNullOrWhiteSpace($Nome)) { return $false }
|
|
99
|
+
if ($Nome -cmatch '^[a-z0-9][a-z0-9-]*$') { return $true }
|
|
100
|
+
return $false
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function Test-AuroqNode {
|
|
104
|
+
param([string]$Versao = '')
|
|
105
|
+
if ([string]::IsNullOrWhiteSpace($Versao)) { return $false }
|
|
106
|
+
$limpa = $Versao.TrimStart('v')
|
|
107
|
+
$maior = ($limpa -split '\.')[0]
|
|
108
|
+
$numero = 0
|
|
109
|
+
if (-not [int]::TryParse($maior, [ref]$numero)) { return $false }
|
|
110
|
+
return ($numero -ge $AuroqNodeMin)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function Get-AuroqNodeZip {
|
|
114
|
+
param([string]$Versao = '', [string]$Arquitetura = 'AMD64')
|
|
115
|
+
$alvo = 'x64'
|
|
116
|
+
if ($Arquitetura -eq 'ARM64') { $alvo = 'arm64' }
|
|
117
|
+
return "node-v$Versao-win-$alvo.zip"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# nova | vazia | auroq | ocupada - decidido ANTES de escrever qualquer coisa.
|
|
121
|
+
function Get-AuroqEstadoPasta {
|
|
122
|
+
param([string]$Caminho = '')
|
|
123
|
+
if (-not (Test-Path $Caminho)) { return 'nova' }
|
|
124
|
+
if (Test-Path (Join-Path $Caminho '.auroq-core')) { return 'auroq' }
|
|
125
|
+
$itens = @(Get-ChildItem -LiteralPath $Caminho -Force -ErrorAction SilentlyContinue |
|
|
126
|
+
Where-Object { $_.Name -ne 'desktop.ini' -and $_.Name -ne 'Thumbs.db' -and $_.Name -ne '.DS_Store' })
|
|
127
|
+
if ($itens.Count -eq 0) { return 'vazia' }
|
|
128
|
+
return 'ocupada'
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# --- O motor visivel pra quem abre pelo icone (sec. 5.4) --------------------------
|
|
132
|
+
# No Windows o programa aberto pelo Menu Iniciar herda o ambiente do USUARIO.
|
|
133
|
+
# Gravar no escopo da maquina inteira exigiria elevacao - o PRD proibe pedir isso.
|
|
134
|
+
|
|
135
|
+
function Set-AuroqPath {
|
|
136
|
+
param([string]$Bin = '')
|
|
137
|
+
$atual = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
138
|
+
if (-not $atual) { $atual = '' }
|
|
139
|
+
$partes = @($atual -split ';' | Where-Object { $_ -and ($_ -ne $Bin) })
|
|
140
|
+
$novo = (@($Bin) + $partes) -join ';'
|
|
141
|
+
[Environment]::SetEnvironmentVariable('Path', $novo, 'User')
|
|
142
|
+
$env:Path = "$Bin;$env:Path"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# --- Passo 1: diagnostico (sec. 5.1) ----------------------------------------------
|
|
146
|
+
|
|
147
|
+
function Test-AuroqMaquina {
|
|
148
|
+
Write-AuroqPasso 'Vendo o seu computador...'
|
|
149
|
+
|
|
150
|
+
if (-not [Environment]::Is64BitProcess) {
|
|
151
|
+
Write-AuroqErro 'Voce abriu a versao de 32 bits do PowerShell.' 'Feche esta janela. No menu Iniciar procure por "Windows PowerShell" (sem x86), abra e cole o comando de novo.'
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
$build = 0
|
|
155
|
+
if ($env:AUROQ_INSTALL_FAKE_BUILD) {
|
|
156
|
+
$build = [int]$env:AUROQ_INSTALL_FAKE_BUILD
|
|
157
|
+
} else {
|
|
158
|
+
try { $build = [System.Environment]::OSVersion.Version.Build } catch { $build = $AuroqBuildMin }
|
|
159
|
+
}
|
|
160
|
+
if ($build -lt $AuroqBuildMin) {
|
|
161
|
+
Write-AuroqErro "Seu Windows esta numa versao antiga (compilacao $build) e o sistema precisa da 1809 ou mais nova." 'Rode o Windows Update ate o fim e tente de novo, ou fale com o suporte antes de continuar.'
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
$chip = $env:PROCESSOR_ARCHITECTURE
|
|
165
|
+
if (-not $chip) { $chip = 'AMD64' }
|
|
166
|
+
Write-AuroqOk "Windows 64 bits, compilacao $build - serve"
|
|
167
|
+
|
|
168
|
+
$livreMb = 999999
|
|
169
|
+
if ($env:AUROQ_INSTALL_FAKE_DISCO_MB) {
|
|
170
|
+
$livreMb = [int]$env:AUROQ_INSTALL_FAKE_DISCO_MB
|
|
171
|
+
} else {
|
|
172
|
+
try {
|
|
173
|
+
$unidade = (Get-AuroqHome).Substring(0, 1)
|
|
174
|
+
$drive = Get-PSDrive -Name $unidade -ErrorAction SilentlyContinue
|
|
175
|
+
if ($drive -and $drive.Free) { $livreMb = [int]($drive.Free / 1MB) }
|
|
176
|
+
} catch {
|
|
177
|
+
$livreMb = 999999
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if ($livreMb -lt $AuroqDiscoMinMb) {
|
|
181
|
+
Write-AuroqErro "Falta espaco no disco: sobram $livreMb MB e sao necessarios pelo menos 2 GB." 'Libere espaco (Configuracoes > Sistema > Armazenamento) e rode o mesmo comando de novo.'
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if ($env:AUROQ_INSTALL_FAKE_SEM_INTERNET) {
|
|
185
|
+
Write-AuroqErro 'Nao consegui falar com a internet.' 'Conecte na internet e rode o mesmo comando de novo. Nada foi instalado pela metade.'
|
|
186
|
+
}
|
|
187
|
+
if (-not $env:AUROQ_INSTALL_DRY_RUN) {
|
|
188
|
+
try {
|
|
189
|
+
Invoke-WebRequest -Uri 'https://registry.npmjs.org/' -Method Head -TimeoutSec 15 -UseBasicParsing | Out-Null
|
|
190
|
+
} catch {
|
|
191
|
+
Write-AuroqErro 'Nao consegui falar com a internet.' 'Conecte na internet e rode o mesmo comando de novo. Nada foi instalado pela metade.'
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
Write-AuroqLog 'diagnostico' "build=$build chip=$chip disco_mb=$livreMb"
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# --- Passo 2: Git (sec. 5.2) ------------------------------------------------------
|
|
198
|
+
|
|
199
|
+
function Test-AuroqGitResponde {
|
|
200
|
+
try {
|
|
201
|
+
$null = & git --version 2>$null
|
|
202
|
+
if ($LASTEXITCODE -eq 0) { return $true }
|
|
203
|
+
} catch {
|
|
204
|
+
# segue pro caminho padrao
|
|
205
|
+
}
|
|
206
|
+
# Dois lugares, porque sao duas instalacoes possiveis: com administrador o Git
|
|
207
|
+
# vai pra Program Files; sem administrador ele vai pra pasta do usuario. Olhar
|
|
208
|
+
# so o primeiro fazia o script jurar que o Git nao existe e ficar esperando sem fim.
|
|
209
|
+
$candidatos = @(
|
|
210
|
+
(Join-Path $env:ProgramFiles 'Git\cmd\git.exe'),
|
|
211
|
+
(Join-Path ${env:ProgramFiles(x86)} 'Git\cmd\git.exe'),
|
|
212
|
+
(Join-Path $env:LOCALAPPDATA 'Programs\Git\cmd\git.exe')
|
|
213
|
+
)
|
|
214
|
+
foreach ($padrao in $candidatos) {
|
|
215
|
+
if ($padrao -and (Test-Path $padrao)) {
|
|
216
|
+
$env:Path = "$(Split-Path $padrao);$env:Path"
|
|
217
|
+
return $true
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return $false
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function Install-AuroqGit {
|
|
224
|
+
Write-AuroqPasso 'Verificando o Git (o programa que guarda as versoes do seu trabalho)...'
|
|
225
|
+
|
|
226
|
+
if ($env:AUROQ_INSTALL_DRY_RUN) { Write-AuroqOk 'Git - seria verificado aqui'; return }
|
|
227
|
+
|
|
228
|
+
if (Test-AuroqGitResponde) {
|
|
229
|
+
Write-AuroqOk 'Git ja estava instalado'
|
|
230
|
+
Write-AuroqLog 'git' 'ja-existia'
|
|
231
|
+
return
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
$temWinget = $false
|
|
235
|
+
try {
|
|
236
|
+
$null = & winget --version 2>$null
|
|
237
|
+
if ($LASTEXITCODE -eq 0) { $temWinget = $true }
|
|
238
|
+
} catch {
|
|
239
|
+
$temWinget = $false
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if ($temWinget) {
|
|
243
|
+
Write-AuroqAviso 'Falta instalar o Git. Vai aparecer uma janela pedindo permissao.'
|
|
244
|
+
Write-AuroqDiz ' Se ela perguntar so "Sim ou Nao", clique em Sim.'
|
|
245
|
+
Write-AuroqDiz ' Se ela pedir SENHA DE ADMINISTRADOR e voce nao tiver, pode fechar:'
|
|
246
|
+
Write-AuroqDiz ' eu instalo de outro jeito, que nao precisa de administrador.'
|
|
247
|
+
& winget install --id Git.Git -e --source winget --accept-package-agreements --accept-source-agreements | Out-Null
|
|
248
|
+
Start-Sleep -Seconds 3
|
|
249
|
+
if (Test-AuroqGitResponde) {
|
|
250
|
+
Write-AuroqOk 'Git instalado'
|
|
251
|
+
Write-AuroqLog 'git' 'instalado-winget'
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
# Nao morre aqui. Quem nao e administrador NUNCA vai conseguir passar dessa
|
|
255
|
+
# janela, e mandar "rode de novo e clique em Sim" tranca essa pessoa num
|
|
256
|
+
# loop. O caminho de baixo instala sem administrador nenhum.
|
|
257
|
+
Write-AuroqAviso 'A janela de permissao nao passou. Vou pelo caminho que nao precisa de administrador.'
|
|
258
|
+
Write-AuroqLog 'git' 'winget-nao-passou'
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
# Duas situacoes caem aqui: Windows 10 antigo sem winget, e aluno sem direito
|
|
262
|
+
# de administrador. O instalador oficial do Git resolve as duas: ele declara
|
|
263
|
+
# `PrivilegesRequired=none` e sabe instalar so pro usuario, em %LOCALAPPDATA%.
|
|
264
|
+
Write-AuroqAviso 'Vou abrir a pagina oficial do Git no seu navegador.'
|
|
265
|
+
Write-AuroqDiz ' 1. Baixe o instalador que a pagina oferecer'
|
|
266
|
+
Write-AuroqDiz ' 2. De dois cliques no arquivo baixado'
|
|
267
|
+
Write-AuroqDiz ' 3. Se ele perguntar para quem instalar, escolha a opcao de instalar'
|
|
268
|
+
Write-AuroqDiz ' SO PRA VOCE - ela nao pede senha de administrador'
|
|
269
|
+
Write-AuroqDiz ' 4. Clique em "Next" em todas as telas e depois em "Install"'
|
|
270
|
+
Write-AuroqDiz ' 5. No fim, clique em "Finish" e volte pra ca - eu espero'
|
|
271
|
+
Start-Process 'https://git-scm.com/downloads/win'
|
|
272
|
+
|
|
273
|
+
# 20 minutos de espera pelo aluno. O teto e regulavel so pra maquina limpa do
|
|
274
|
+
# CI nao gastar 20 minutos de runner provando uma mensagem.
|
|
275
|
+
$teto = 1200
|
|
276
|
+
if ($env:AUROQ_INSTALL_ESPERA_GIT) { $teto = [int]$env:AUROQ_INSTALL_ESPERA_GIT }
|
|
277
|
+
$esperou = 0
|
|
278
|
+
while ($esperou -lt $teto) {
|
|
279
|
+
if (Test-AuroqGitResponde) {
|
|
280
|
+
Write-AuroqOk 'Git instalado'
|
|
281
|
+
Write-AuroqLog 'git' 'instalado-manual'
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
Start-Sleep -Seconds 10
|
|
285
|
+
$esperou = $esperou + 10
|
|
286
|
+
if (($esperou % 120) -eq 0) { Write-AuroqDiz " ainda esperando... ($esperou s)" }
|
|
287
|
+
}
|
|
288
|
+
Write-AuroqErro 'A instalacao do Git nao terminou.' 'Termine a instalacao e rode o mesmo comando de novo - nada do que ja foi feito se perde.'
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
# --- Passo 3: o motor (sec. 5.3) --------------------------------------------------
|
|
292
|
+
|
|
293
|
+
function Install-AuroqNode {
|
|
294
|
+
Write-AuroqPasso 'Verificando o motor do sistema...'
|
|
295
|
+
|
|
296
|
+
if ($env:AUROQ_INSTALL_DRY_RUN) { Write-AuroqOk 'Motor - seria instalado em uma pasta sua, sem senha'; return }
|
|
297
|
+
|
|
298
|
+
$atual = ''
|
|
299
|
+
try {
|
|
300
|
+
$atual = (& node --version 2>$null)
|
|
301
|
+
} catch {
|
|
302
|
+
$atual = ''
|
|
303
|
+
}
|
|
304
|
+
if (Test-AuroqNode $atual) {
|
|
305
|
+
Write-AuroqOk "O motor ja estava instalado ($atual)"
|
|
306
|
+
Write-AuroqLog 'motor' "ja-existia versao=$atual"
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
if ($atual) {
|
|
310
|
+
Write-AuroqAviso "Voce ja tinha um motor antigo ($atual); vou instalar um novo do lado, sem mexer no seu."
|
|
311
|
+
}
|
|
312
|
+
Write-AuroqDiz ' (e um programa que fica numa pasta sua, nao pede senha e nao mexe em nada do seu Windows)'
|
|
313
|
+
|
|
314
|
+
$chip = $env:PROCESSOR_ARCHITECTURE
|
|
315
|
+
if (-not $chip) { $chip = 'AMD64' }
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
$indice = Invoke-RestMethod -Uri 'https://nodejs.org/dist/index.json' -TimeoutSec 30 -UseBasicParsing
|
|
319
|
+
} catch {
|
|
320
|
+
Write-AuroqErro 'Nao consegui baixar o motor do sistema.' 'Confira a internet (ou o antivirus, se houver) e rode o mesmo comando de novo.'
|
|
321
|
+
}
|
|
322
|
+
$escolhido = $indice | Where-Object { $_.version -like 'v24.*' } | Select-Object -First 1
|
|
323
|
+
if (-not $escolhido) { $escolhido = $indice | Where-Object { $_.lts } | Select-Object -First 1 }
|
|
324
|
+
if (-not $escolhido) {
|
|
325
|
+
Write-AuroqErro 'Nao consegui descobrir qual motor baixar.' 'Rode o mesmo comando de novo em alguns minutos. Se insistir, chame o suporte.'
|
|
326
|
+
}
|
|
327
|
+
$versao = $escolhido.version.TrimStart('v')
|
|
328
|
+
$zip = Get-AuroqNodeZip $versao $chip
|
|
329
|
+
$destino = Join-Path $env:TEMP $zip
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
Invoke-WebRequest -Uri "https://nodejs.org/dist/v$versao/$zip" -OutFile $destino -TimeoutSec 600 -UseBasicParsing
|
|
333
|
+
} catch {
|
|
334
|
+
Write-AuroqErro 'O download do motor nao completou.' 'Pode ser antivirus ou rede instavel. Rode o mesmo comando de novo; se repetir, chame o suporte.'
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
# Sem conferir a soma oficial, nao instala.
|
|
338
|
+
try {
|
|
339
|
+
$somas = (Invoke-WebRequest -Uri "https://nodejs.org/dist/v$versao/SHASUMS256.txt" -TimeoutSec 60 -UseBasicParsing).Content
|
|
340
|
+
$linha = ($somas -split "`n" | Where-Object { $_ -match [regex]::Escape($zip) } | Select-Object -First 1)
|
|
341
|
+
$esperado = ($linha -split '\s+')[0]
|
|
342
|
+
$obtido = (Get-FileHash -Path $destino -Algorithm SHA256).Hash
|
|
343
|
+
} catch {
|
|
344
|
+
$esperado = ''
|
|
345
|
+
$obtido = 'x'
|
|
346
|
+
}
|
|
347
|
+
if (-not $esperado -or ($esperado.ToLower() -ne $obtido.ToLower())) {
|
|
348
|
+
Remove-Item $destino -Force -ErrorAction SilentlyContinue
|
|
349
|
+
Write-AuroqErro 'O arquivo do motor baixou com defeito.' 'Rode o mesmo comando de novo - o arquivo estragado ja foi apagado.'
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
# mark-of-the-web: sem desbloquear, o Windows recusa abrir o que veio da internet
|
|
353
|
+
Unblock-File -Path $destino -ErrorAction SilentlyContinue
|
|
354
|
+
|
|
355
|
+
$nodeDir = Get-AuroqNodeDir
|
|
356
|
+
$pai = Split-Path $nodeDir
|
|
357
|
+
try {
|
|
358
|
+
if (-not (Test-Path $pai)) { New-Item -ItemType Directory -Path $pai -Force | Out-Null }
|
|
359
|
+
if (Test-Path $nodeDir) { Remove-Item $nodeDir -Recurse -Force -ErrorAction SilentlyContinue }
|
|
360
|
+
Expand-Archive -Path $destino -DestinationPath $pai -Force
|
|
361
|
+
$extraido = Join-Path $pai "node-v$versao-win-$(if ($chip -eq 'ARM64') { 'arm64' } else { 'x64' })"
|
|
362
|
+
Rename-Item -Path $extraido -NewName 'node' -Force
|
|
363
|
+
} catch {
|
|
364
|
+
Write-AuroqErro 'Nao consegui guardar o motor na sua pasta.' 'Rode o mesmo comando de novo. Se repetir, mande pro suporte o arquivo install.log da pasta .auroq.'
|
|
365
|
+
}
|
|
366
|
+
Remove-Item $destino -Force -ErrorAction SilentlyContinue
|
|
367
|
+
|
|
368
|
+
Set-AuroqPath $nodeDir
|
|
369
|
+
# instalar ferramenta depois nao pode pedir elevacao
|
|
370
|
+
$env:npm_config_prefix = $nodeDir
|
|
371
|
+
|
|
372
|
+
Write-AuroqOk "Motor instalado ($versao)"
|
|
373
|
+
Write-AuroqLog 'motor' "instalado versao=$versao chip=$chip"
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
# --- Passo 4: login da mentoria (sec. 5.5) ----------------------------------------
|
|
377
|
+
|
|
378
|
+
function Invoke-AuroqLogin {
|
|
379
|
+
Write-AuroqPasso 'Agora entre com o seu acesso da Mentoria Arcane.'
|
|
380
|
+
|
|
381
|
+
if ($env:AUROQ_INSTALL_DRY_RUN) { Write-AuroqOk 'Login - seria pedido aqui (e-mail e senha da plataforma)'; return }
|
|
382
|
+
|
|
383
|
+
# `check-access` e a mesma regua do resto do sistema: sai com sucesso so com
|
|
384
|
+
# contrato ativo conferido agora. Sem sessao salva, ele mesmo pede e-mail e
|
|
385
|
+
# senha; com sessao boa, passa direto e nao pergunta de novo.
|
|
386
|
+
#
|
|
387
|
+
# NAO usar `whoami` aqui: ele imprime "Nao autenticado" e mesmo assim sai com
|
|
388
|
+
# sucesso. Usado como pergunta de sim/nao, ele dizia "voce ja estava logado"
|
|
389
|
+
# pra quem nunca logou, pulava o portao e deixava a conta sem acesso chegar ate
|
|
390
|
+
# a criacao da pasta.
|
|
391
|
+
& npx -y auroq-os@latest check-access
|
|
392
|
+
if ($LASTEXITCODE -ne 0) {
|
|
393
|
+
Write-AuroqLog 'login' 'recusado'
|
|
394
|
+
Write-Host ''
|
|
395
|
+
Write-Host ' Sem acesso ativo, a instalacao para aqui - e nada foi criado no seu computador.' -ForegroundColor DarkGray
|
|
396
|
+
Write-Host " O que fazer agora: fale com o suporte $AuroqSuporte" -ForegroundColor DarkGray
|
|
397
|
+
Write-Host ''
|
|
398
|
+
exit 1
|
|
399
|
+
}
|
|
400
|
+
Write-AuroqLog 'login' 'ok'
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
# --- Passo 5: pasta do negocio (sec. 5.6) -----------------------------------------
|
|
404
|
+
|
|
405
|
+
function Get-AuroqPasta {
|
|
406
|
+
Write-AuroqPasso 'Qual o nome da pasta do seu negocio?'
|
|
407
|
+
Write-AuroqDiz '(so letras minusculas e hifen - ex: minha-empresa)'
|
|
408
|
+
|
|
409
|
+
$nome = $env:AUROQ_INSTALL_PASTA
|
|
410
|
+
$tentativas = 0
|
|
411
|
+
|
|
412
|
+
while ($true) {
|
|
413
|
+
if (-not $nome) { $nome = Read-Host ' Nome' }
|
|
414
|
+
|
|
415
|
+
if (Test-AuroqPasta $nome) {
|
|
416
|
+
$alvo = Join-Path (Get-AuroqHome) $nome
|
|
417
|
+
$estado = Get-AuroqEstadoPasta $alvo
|
|
418
|
+
if ($estado -eq 'auroq') {
|
|
419
|
+
Write-Host ''
|
|
420
|
+
Write-AuroqAviso "Ja existe um Auroq em $alvo - nao vou mexer nele."
|
|
421
|
+
Write-AuroqDiz 'Pra conferir se esta tudo certo la, abra essa pasta e rode:'
|
|
422
|
+
Write-AuroqDiz ' auroq-os doctor'
|
|
423
|
+
Write-AuroqLog 'pasta' 'ja-tinha-auroq'
|
|
424
|
+
exit 0
|
|
425
|
+
}
|
|
426
|
+
if ($estado -eq 'ocupada') {
|
|
427
|
+
Write-AuroqAviso "A pasta $nome ja existe e tem coisa sua dentro. Escolha outro nome."
|
|
428
|
+
$nome = ''
|
|
429
|
+
} else {
|
|
430
|
+
$script:AuroqPastaAlvo = $alvo
|
|
431
|
+
break
|
|
432
|
+
}
|
|
433
|
+
} elseif ([string]::IsNullOrWhiteSpace($nome)) {
|
|
434
|
+
# Enter vazio so repete a pergunta - o aluno ainda nao escreveu nada.
|
|
435
|
+
$nome = ''
|
|
436
|
+
} else {
|
|
437
|
+
Write-AuroqDiz 'Esse nome nao serve: use so letras minusculas, numeros e hifen.'
|
|
438
|
+
Write-AuroqDiz 'Exemplo bom: minha-empresa'
|
|
439
|
+
$nome = ''
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
$tentativas = $tentativas + 1
|
|
443
|
+
if ($tentativas -ge 5) {
|
|
444
|
+
Write-AuroqErro 'Nao consegui um nome valido pra pasta.' 'Rode o mesmo comando de novo e escreva algo como: minha-empresa'
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if ($env:AUROQ_INSTALL_DRY_RUN) { Write-AuroqOk "Pasta $script:AuroqPastaAlvo - seria criada aqui"; return }
|
|
449
|
+
|
|
450
|
+
try {
|
|
451
|
+
if (-not (Test-Path $script:AuroqPastaAlvo)) {
|
|
452
|
+
New-Item -ItemType Directory -Path $script:AuroqPastaAlvo -Force | Out-Null
|
|
453
|
+
}
|
|
454
|
+
} catch {
|
|
455
|
+
Write-AuroqErro "Nao consegui criar a pasta $script:AuroqPastaAlvo." 'Confira se voce tem permissao de escrita na sua pasta pessoal e rode de novo.'
|
|
456
|
+
}
|
|
457
|
+
Write-AuroqLog 'pasta' 'criada'
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
# --- Passo 6: montar o Auroq --------------------------------------------------
|
|
461
|
+
|
|
462
|
+
function Invoke-AuroqInit {
|
|
463
|
+
Write-AuroqPasso "Montando o Auroq dentro de $script:AuroqPastaAlvo..."
|
|
464
|
+
|
|
465
|
+
if ($env:AUROQ_INSTALL_DRY_RUN) { Write-AuroqOk 'Sistema - seria montado aqui'; return }
|
|
466
|
+
|
|
467
|
+
Set-Location $script:AuroqPastaAlvo
|
|
468
|
+
& npx -y auroq-os@latest init
|
|
469
|
+
if ($LASTEXITCODE -ne 0) {
|
|
470
|
+
Write-AuroqLog 'init' 'falhou'
|
|
471
|
+
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.'
|
|
472
|
+
}
|
|
473
|
+
Write-AuroqLog 'init' 'ok'
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
# --- Passo 7: fecho -----------------------------------------------------------
|
|
477
|
+
|
|
478
|
+
function Write-AuroqFecho {
|
|
479
|
+
$nome = Split-Path $script:AuroqPastaAlvo -Leaf
|
|
480
|
+
Write-Host ''
|
|
481
|
+
Write-Host ' ---------------------------------------------' -ForegroundColor Magenta
|
|
482
|
+
Write-Host ''
|
|
483
|
+
Write-AuroqDiz "Pronto. O Auroq esta em $script:AuroqPastaAlvo"
|
|
484
|
+
Write-Host ''
|
|
485
|
+
Write-AuroqDiz 'Falta um detalhe importante:'
|
|
486
|
+
Write-Host ''
|
|
487
|
+
Write-AuroqDiz ' 1. FECHE o Claude Code (ou o Codex) por completo e abra de novo'
|
|
488
|
+
Write-AuroqDiz ' - sem isso ele nao enxerga o que acabou de ser instalado'
|
|
489
|
+
Write-AuroqDiz " 2. Abra a pasta $nome"
|
|
490
|
+
Write-AuroqDiz ' 3. Chame o Ops: /AuroqOS:agents:ops (no Codex: $ops)'
|
|
491
|
+
Write-AuroqDiz ' 4. Digite: *bootstrap'
|
|
492
|
+
Write-Host ''
|
|
493
|
+
Write-AuroqDiz 'O Ops instala o resto e te guia daqui pra frente.'
|
|
494
|
+
Write-Host ''
|
|
495
|
+
Write-AuroqLog 'fim' "ok pasta=$nome"
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
# --- Fluxo --------------------------------------------------------------------
|
|
499
|
+
|
|
500
|
+
function Invoke-AuroqInstalacao {
|
|
501
|
+
Write-AuroqTitulo 'Auroq OS - instalacao'
|
|
502
|
+
Test-AuroqMaquina
|
|
503
|
+
Install-AuroqGit
|
|
504
|
+
Install-AuroqNode
|
|
505
|
+
Invoke-AuroqLogin
|
|
506
|
+
Get-AuroqPasta
|
|
507
|
+
Invoke-AuroqInit
|
|
508
|
+
Write-AuroqFecho
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
# Carregado pelos testes: so define as funcoes e sai.
|
|
512
|
+
if (-not $env:AUROQ_INSTALL_LIB) {
|
|
513
|
+
$script:AuroqPastaAlvo = ''
|
|
514
|
+
Invoke-AuroqInstalacao
|
|
515
|
+
}
|