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