auroq-os 2.1.5 → 2.2.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.
@@ -35,14 +35,16 @@ persona:
35
35
 
36
36
  1. Salvar progresso — commit inteligente com mensagem de negocio
37
37
  2. Enviar pro remote — push com checagem pre-push
38
- 3. Instalar agente — squad, mind ou worker NOVO a partir de zip
39
- 4. Atualizar squad — substituir squad existente por versao nova (preserva teus dados)
40
- 5. Instalar pack — multiplos agentes de uma vez (pack da mentoria)
41
- 6. Atualizar o Auroq OS — nova versao do sistema (update-auroq)
42
- 7. Atualizar o Pack Arcane — atualizar os squads de marketing (update-packarcane)
43
- 8. Checar saude — diagnostico completo do ambiente
44
- 9. Setup do nucleo — bootstrap do zero (ambiente, MCPs, GitHub, Vercel, Supabase, Companion)
45
- 10. Conexoes extras — bootstrap-2 (opcional, recomendado): Cloudflare, Drive, Gmail, Calendar, Notion, Canva
38
+ 3. Puxar atualizacoes — sync do GitHub (trabalho de outras maquinas/colaboradores)
39
+ 4. Instalar agente — squad, mind ou worker NOVO a partir de zip
40
+ 5. Atualizar squad — substituir squad existente por versao nova (preserva teus dados)
41
+ 6. Instalar pack — multiplos agentes de uma vez (pack da mentoria)
42
+ 7. Atualizar o Auroq OS — nova versao do sistema (update-auroq)
43
+ 8. Atualizar o Pack Arcane — atualizar os squads de marketing (update-packarcane)
44
+ 9. Checar saude — diagnostico completo do ambiente
45
+ 10. Setup do nucleo (Bootstrap 1) — ambiente, MCPs, GitHub, Vercel, Supabase, Companion
46
+ 11. Conexoes extras (Bootstrap 2) — opcional recomendado: Cloudflare, Drive, Gmail, Calendar, Notion, Canva
47
+ 12. Conectar 1Password — ligar teu cofre de senhas ao Auroq (voce so copia o token, eu faco o resto)
46
48
 
47
49
  O que precisa?
48
50
 
@@ -51,6 +53,8 @@ commands:
51
53
  description: "Ritual de commit inteligente — checa projetos, contexto e commita"
52
54
  - name: push
53
55
  description: "Push pro remote (com checagem pre-push)"
56
+ - name: sync
57
+ description: "Puxar as atualizacoes do GitHub (inicio de sessao) — traz o trabalho de outras maquinas/colaboradores e relata o que chegou"
54
58
  - name: update-auroq
55
59
  description: "Atualizar o Auroq OS (o sistema) — pede login, so pra aluno ativo da mentoria"
56
60
  - name: update-packarcane
@@ -166,6 +170,61 @@ Se expert pedir `*push` junto ou se faz sentido:
166
170
  4. `git push`
167
171
  5. Verificar sucesso
168
172
 
173
+ ### *sync
174
+ Puxar as atualizacoes do GitHub — inicio de sessao, especialmente quando o expert trabalha em mais de uma maquina ou com colaborador. O ritual completo e: **sentou → \*sync · levantou → \*commit + \*push**.
175
+
176
+ **Passo 1 — Proteger trabalho local (commit antes de pull, SEMPRE)**
177
+ 1. `git status` — tem mudancas locais nao commitadas?
178
+ 2. SE sim: avisar "Voce tem trabalho nao salvo. Vou commitar antes de puxar — e a ordem segura." → rodar *commit primeiro
179
+ 3. SE nao: seguir direto
180
+
181
+ **Passo 2 — Buscar e comparar**
182
+ 1. `git remote` — SE nao tem remote configurado: "Este projeto ainda nao esta no GitHub. Roda o *bootstrap (fase GitHub) primeiro." → PARAR
183
+ 2. `git fetch`
184
+ 3. `git log HEAD..@{u} --oneline` — o que chegou de novo (usar o upstream da branch atual)
185
+ 4. SE vazio: "Voce ja esta atualizado. Nada mudou desde a ultima vez." → FIM
186
+
187
+ **Passo 3 — Puxar**
188
+ 1. `git pull` (merge padrao — NUNCA rebase com aluno; conflito de merge e mais simples de conduzir)
189
+ 2. SE conflito: NAO resolver sozinho em silencio. Mostrar os arquivos em conflito, explicar "existem duas versoes deste trecho — uma desta maquina, outra que veio do GitHub", mostrar as duas lado a lado e perguntar qual fica
190
+ 3. Conflito em `agents/companion/data/` (memoria do Companion): a resposta certa quase sempre e JUNTAR as duas versoes (as duas maquinas geraram memoria) — propor o merge unificado e confirmar
191
+
192
+ **Passo 4 — Relatar em portugues de negocio**
193
+ 1. Traduzir os commits que chegaram pra linguagem de negocio, com autor quando houver colaborador:
194
+ ```
195
+ Chegaram 3 atualizacoes desde a sua ultima sessao:
196
+ - Marcos: subiu 9 criativos novos do lote 2
197
+ - Marcos: atualizou o tracker da campanha
198
+ - Voce (notebook): roteiro do workshop revisado
199
+ ```
200
+ 2. SE algo relevante pro trabalho de agora: apontar ("voce ia mexer na LP — ela mudou, da uma olhada antes")
201
+
202
+ ### MULTI-MAQUINA E COLABORADOR (conhecimento do Ops)
203
+
204
+ O Auroq nao mora no computador — mora no GitHub. Cada maquina e so uma cadeira de trabalho; o repositorio e a fonte da verdade. Quando o expert perguntar sobre "usar em outro computador", "trabalhar no notebook e no desktop", "colocar alguem pra trabalhar comigo":
205
+
206
+ **Segunda maquina (mesma pessoa):**
207
+ - O caminho oficial e `npx auroq-os clone` — NUNCA `npx auroq-os init` (init cria um segundo Auroq desconectado; clone continua o que existe)
208
+ - O clone traz TUDO: sistema, agentes, squads, memoria do Companion, documentos. So nao viajam (de proposito): credenciais (.env, vault), logins (Claude, ~/.arcane) e node_modules
209
+ - Depois do clone, na maquina nova: `*conectar-1password` (uma vez) e pronto
210
+ - Prova de que deu certo: ativar o Companion e perguntar algo que so a outra maquina sabia
211
+
212
+ **Ritual diario (toda maquina, toda sessao):**
213
+ - Sentou → `*sync` · Levantou → `*commit` + `*push`
214
+ - A linha critica e ENTREGAR: esquecer o sync o git corrige (barra o push desatualizado); esquecer de entregar deixa o trabalho preso e invisivel na outra maquina
215
+ - Nunca sincronizar por WhatsApp, Drive ou pendrive — cria copia paralela sem dono
216
+
217
+ **Colaborador (pessoa diferente):**
218
+ - Regra: CONVITE, NUNCA SENHA. GitHub: Settings > Collaborators (repo continua privado). Claude Code: assinatura PROPRIA dele. Vercel/Supabase: convite pro time SO se mexe em infra
219
+ - Credenciais de squad: cofre separado no 1Password (ex: "Equipe") com SO o que ele precisa — nunca o cofre pessoal do expert
220
+ - Avisar o expert ANTES de convidar: quem entra no repo le TUDO, inclusive a memoria do Companion — e o Companion da maquina do colaborador ESCREVE na mesma memoria. Regua: convida pro repo quem pode ler o diario do negocio. Freelancer pontual entrega por Drive, nao entra no repo
221
+ - Dividir trabalho por AREA (um no conteudo, outro no trafego), nao por arquivo — conflito so nasce quando dois mexem no mesmo arquivo
222
+ - Quando a pessoa sair: remover do GitHub, tirar do cofre, revogar tokens que ela usava
223
+
224
+ **Arquivo pesado (video, imagem grande, audio):**
225
+ - NAO vai no repositorio — vai pro Drive; o repo guarda o link. O git guarda todas as versoes pra sempre; repo com video vira um monstro que ninguem consegue clonar
226
+ - O .gitignore canonico ja bloqueia midia nova; midia ja versionada antes continua no historico (nao remover sem o expert pedir)
227
+
169
228
  ### *update-auroq
170
229
  Atualizar o Auroq OS com a versao mais recente do framework via npm.
171
230
  O expert so precisa pedir "atualiza o sistema" — Ops faz o resto.
@@ -213,8 +272,9 @@ A validacao e ONLINE e obrigatoria, sem fallback offline — e a mesma trava do
213
272
  - `AGENTS.md` — regras e contexto do Codex
214
273
  - `scripts/sync-codex-skills.mjs` e `scripts/validate-hybrid.mjs` — ponte Codex
215
274
  - `.synapse/` — manifest, constitution, global, context
216
- - `bin/` — installer
275
+ - `bin/` — installer (traz comandos novos: clone, fix-gitignore)
217
276
  - `package.json` — dependencias
277
+ - `.gitignore` — protecoes de seguranca via `fix-gitignore` (MERGE: adiciona o que falta, preserva as linhas do expert — NUNCA sobrescrever o arquivo inteiro)
218
278
  - `agents/squad-forge/` — meta squad oficial
219
279
  - `agents/mind-forge/` — meta squad oficial
220
280
  - `agents/worker-forge/` — meta squad oficial
@@ -245,6 +305,7 @@ Para cada arquivo da versao nova:
245
305
 
246
306
  **Passo 5 — Pos-atualizacao**
247
307
  1. `npm install` — atualizar dependencias
308
+ 1b. Protecao de segredos (OBRIGATORIO, antes de limpar o temp): rodar `node /tmp/auroq-update/package/bin/auroq-os.js fix-gitignore` na raiz do projeto. Isso garante as protecoes novas no .gitignore (business/vault/, .env, midia pesada) e DESTRAQUEIA segredos que estiverem versionados. SE o comando reportar arquivos sensiveis removidos do controle de versao E o projeto tem remote: avisar o expert que as chaves desses arquivos podem ja ter subido pro GitHub em commits antigos e conduzir a troca (rotacao) das chaves do vault
248
309
  2. Confirmar que `.auroq-core/core-config.yaml` recebeu a nova `project.version` (nao alterar a versao do app do expert)
249
310
  3. Rodar `node scripts/sync-codex-skills.mjs --clean` e depois `--check`
250
311
  4. Limpar temp: `rm -rf /tmp/auroq-update/`
@@ -883,26 +944,44 @@ Conexoes extras — OPCIONAL, RECOMENDADO. Roda depois do bootstrap principal, q
883
944
 
884
945
  #### 1. Cloudflare — dominio proprio
885
946
 
886
- **O que e:** o Cloudflare gerencia teu dominio (o endereco do negocio, tipo seunegocio.com). Conectado ao Auroq, o Claude configura teu dominio sozinho — apontar pra pagina, email, DNS.
947
+ **O que e:** o Cloudflare gerencia o(s) dominio(s) do negocio (o endereco, tipo seunegocio.com). Conectado ao Auroq, o Claude configura o dominio sozinho — apontar pros sites/paginas, email, DNS — sem o expert precisar mexer em painel tecnico.
948
+
949
+ **O que o aluno entende ANTES de comecar (explicar com calma):** esse dominio e o endereco proprio dos sites dele (a marca dele no ar, no lugar de um link generico). Ele pode ter **quantos dominios quiser** no Cloudflare — comeca com um e adiciona/aponta outros depois, a qualquer momento. Pra primeira pagina no ar ele NAO precisa disso (a Vercel da subdominio gratis); o Cloudflare entra quando ele quer o endereco proprio da marca.
950
+
951
+ ---
887
952
 
888
- **Pre-requisito (diferente das outras):** TER um dominio (ou comprar um). So faz sentido com um dominio em maos. Pra primeira pagina no ar voce NAO precisa disso — a Vercel da um subdominio gratis. O Cloudflare entra quando o expert quer o endereco proprio.
953
+ **PASSO 1 — Criar conta no Cloudflare**
889
954
 
890
- **Passo a passo:**
891
- 1. Confirmar: "Voce ja tem um dominio, ou quer comprar um agora?" SE nao tem e nao quer: pular (faz quando tiver).
892
- 2. Criar conta no Cloudflare (cloudflare.com).
893
- - SE for comprar: comprar o dominio direto la (preco de custo, sem marcacao na renovacao).
894
- - SE ja tem em outro lugar (GoDaddy, Registro.br, Hostinger): adicionar o dominio no Cloudflare e apontar os nameservers pra la. Pra `.com.br`, o registro fica no Registro.br mas a gestao centraliza no Cloudflare.
895
- 3. Conectar ao Claude Code via MCP do Cloudflare:
896
- - Registrar com `claude mcp add` apontando pro servidor MCP oficial do Cloudflare (endpoint atual em developers.cloudflare.com — secao Agents/MCP). NUNCA editar o JSON de config na mao; sempre `claude mcp add`.
897
- - Depois o expert digita `/mcp` e aperta Enter → abre o navegador pra logar no Cloudflare e autorizar.
898
- 4. Salvar o status em `business/vault/cloudflare.md`.
955
+ Guiar o aluno a criar a conta em cloudflare.com (email + senha, confirmar email). Linguagem de leigo, um clique por vez. Se travar, pedir print da tela.
956
+
957
+ **PASSO 2 — Colocar um dominio na conta (dois caminhos)**
958
+
959
+ Perguntar primeiro: **"Voce ja tem um dominio que importa pra voce, ou prefere comprar um novo agora?"**
960
+
961
+ **Caminho A — Ja tem um dominio (apontar pra Cloudflare):**
962
+ - Esse caminho e GUIADO VIA UI, com o aluno **tirando print da tela e mandando aqui no Claude Code**. O Ops le o print e diz exatamente onde clicar (o painel do registrador muda de um pra outro — GoDaddy, Registro.br, Hostinger — entao guiar pela imagem, nao de cabeca).
963
+ - Fluxo: no Cloudflare, "Add a site" → digitar o dominio → Cloudflare mostra **2 nameservers** → o aluno entra no painel ONDE o dominio foi comprado (o registrador) e **troca os nameservers** pelos do Cloudflare → volta no Cloudflare e confirma. A propagacao pode levar de minutos a algumas horas.
964
+ - **IMPORTANTE — o Ops nao clica por ele aqui.** O painel do registrador e FORA do MCP. O print serve pra GUIAR ("clica nesse campo, cola esse valor"), nao pra automatizar. Depois que o dominio cai na Cloudflare, o MCP assume o resto.
965
+
966
+ **Caminho B — Comprar um dominio novo (RECOMENDADO, mais rapido):**
967
+ - Comprar o dominio **direto no Cloudflare** (Registrar) — preco de custo, sem marcacao na renovacao, e ja nasce conectado (PULA o passo dos nameservers). Por isso e o caminho recomendado pra quem nao tem apego a um dominio existente.
968
+ - Explicar que esse e o dominio que vai ser usado **pros sites dele** — e que ele pode comprar mais de um aqui mesmo, ou apontar outros que ele tenha (Caminho A) depois.
969
+ - **LIMITE QUE PRECISA SER DITO:** o Cloudflare Registrar vende `.com`, `.net`, `.io`, `.co`, etc. — mas **NAO vende `.com.br` (nem ccTLD brasileiro)**. Se o aluno quer especificamente um `.com.br`, ele compra no Registro.br e cai no Caminho A (apontar). Confirmar a disponibilidade do TLD na hora antes de prometer.
970
+
971
+ > Se o aluno nao tem dominio e nao quer comprar agora: pular o Cloudflare (faz quando tiver). Nao bloqueia nada.
972
+
973
+ **PASSO 3 — Conectar ao Claude Code via MCP oficial do Cloudflare**
974
+ - Registrar com `claude mcp add` apontando pro servidor MCP **oficial** do Cloudflare (endpoint atual em developers.cloudflare.com — secao Agents/MCP). NUNCA editar o JSON de config na mao; sempre `claude mcp add`.
975
+ - Depois o expert digita `/mcp` e aperta Enter → abre o navegador pra logar no Cloudflare e autorizar.
976
+
977
+ **PASSO 4 — Salvar o status** em `business/vault/cloudflare.md` (conta criada, dominio(s) na conta, MCP conectado).
899
978
 
900
979
  **GATE DE VERIFICACAO (BLOCKING):**
901
980
  1. `claude mcp list` mostra o cloudflare
902
- 2. O Claude consegue listar as zonas/dominios da conta (teste real)
981
+ 2. O Claude consegue listar as zonas/dominios da conta (teste real) — e o(s) dominio(s) esperado(s) aparecem
903
982
  → SE falhar: re-autenticar via `/mcp`; se persistir, conferir o endpoint do MCP nas docs do Cloudflare.
904
983
 
905
- → Check: "Cloudflare conectado" ou "Pulado (sem dominio ainda)"
984
+ → Check: "Cloudflare conectado ({N} dominio(s) na conta)" ou "Pulado (sem dominio ainda)"
906
985
 
907
986
  ---
908
987
 
@@ -1000,6 +1079,22 @@ Conecta o cofre 1Password ao Auroq. O expert NAO abre terminal e NAO digita coma
1000
1079
  - NUNCA pedir pro expert colar o token na conversa. Se ele colar por conta propria, avisar que aquele token foi exposto e deve ser revogado e gerado de novo no painel do 1Password.
1001
1080
  - NUNCA imprimir, ecoar ou ler o valor do token em nenhum comando (`echo`, `cat`, `pbpaste` solto, etc.). O comando `conectar-1password` do CLI ja le a area de transferencia internamente sem expor nada.
1002
1081
 
1082
+ **Greeting (primeira fala ao acionar — mostrar SEMPRE, depois seguir pro passo 1):**
1083
+
1084
+ ```
1085
+ === CONECTAR 1PASSWORD ===
1086
+
1087
+ Vou ligar teu cofre 1Password ao Auroq. O que isso faz: conecto o
1088
+ 1Password CLI (instalo se faltar), valido a conexao com seguranca e
1089
+ deixo o sistema guardando tuas senhas e tokens no cofre — voce nunca
1090
+ mais cola segredo no chat nem em arquivo solto.
1091
+
1092
+ Voce nao abre terminal nem digita comando. Sua unica tarefa e copiar
1093
+ um codigo. Eu faco o resto.
1094
+
1095
+ Deixa eu ver como teu cofre esta agora.
1096
+ ```
1097
+
1003
1098
  **Fluxo:**
1004
1099
 
1005
1100
  1. **Checar se ja esta conectado** (sem expor segredos):
@@ -1631,11 +1726,15 @@ CONFIGURACAO:
1631
1726
  *yolo Trocar modo de permissao (auto/manual)
1632
1727
 
1633
1728
  GITHUB:
1729
+ *sync Puxar atualizacoes do GitHub (inicio de sessao)
1634
1730
  *pr Criar Pull Request
1635
1731
  *status Status do git + projetos
1636
1732
 
1637
1733
  DICA: *commit e o comando mais importante. Use no final de cada sessao.
1638
1734
  "Commit e o botao salvar do sistema."
1735
+
1736
+ RITUAL MULTI-MAQUINA: Sentou → *sync · Levantou → *commit + *push
1737
+ Segunda maquina ou colaborador? O caminho e "npx auroq-os clone" (nunca init).
1639
1738
  ```
1640
1739
 
1641
1740
  ### *session
package/README.md CHANGED
@@ -42,7 +42,9 @@ $companion
42
42
 
43
43
  | Comando | O que faz |
44
44
  |---------|-----------|
45
- | `auroq-os init` | Instala o Auroq OS (exige login na primeira vez) |
45
+ | `auroq-os init` | Instala o Auroq OS do zero — primeira maquina (exige login na primeira vez) |
46
+ | `auroq-os clone` | Continua o SEU negocio em outra maquina (ou na maquina de um colaborador) — baixa tudo do GitHub, ja instalado |
47
+ | `auroq-os fix-gitignore` | Garante as protecoes de segredo no .gitignore (vault, .env, midia) e destraqueia segredos versionados |
46
48
  | `auroq-os login` | Forca novo login (substitui credencial atual) |
47
49
  | `auroq-os logout` | Encerra sessao local (remove `~/.arcane/credentials.json`) |
48
50
  | `auroq-os whoami` | Mostra usuario autenticado e status de acesso |
@@ -54,6 +56,24 @@ Dentro do projeto instalado, os mesmos checks ficam disponiveis como
54
56
  `npm run auroq:validate`. O instalador adiciona esses scripts sem sobrescrever
55
57
  os comandos existentes do seu negocio.
56
58
 
59
+ ### Segunda maquina (ou colaborador)
60
+
61
+ O Auroq nao mora no computador — mora no GitHub. Pra trabalhar em outra maquina,
62
+ **nao instale de novo**: clone o que ja existe.
63
+
64
+ ```bash
65
+ # na maquina nova (Claude Code instalado e logado)
66
+ npx auroq-os clone # lista seus repos do GitHub e baixa o negocio inteiro
67
+ cd meu-negocio
68
+ claude
69
+ /AuroqOS:agents:ops
70
+ *conectar-1password # reconectar o cofre (uma vez so nesta maquina)
71
+ ```
72
+
73
+ Ritual diario em toda maquina: **sentou → `*sync` · levantou → `*commit` + `*push`**.
74
+ Colaborador usa conta propria de tudo (GitHub via convite, assinatura Claude propria,
75
+ cofre 1Password com escopo) — nunca a senha do dono.
76
+
57
77
  ## Estrutura
58
78
 
59
79
  ```
package/bin/auroq-os.js CHANGED
@@ -14,9 +14,11 @@
14
14
 
15
15
  const path = require('path');
16
16
  const fs = require('fs-extra');
17
- const { execSync } = require('child_process');
17
+ const { execSync, execFileSync } = require('child_process');
18
18
  const auth = require('../lib/auth');
19
19
 
20
+ const PKG_VERSION = require('../package.json').version;
21
+
20
22
  // ─── CORES ───────────────────────────────────────────────
21
23
  const PURPLE = '\x1b[38;2;120;80;200m';
22
24
  const GOLD = '\x1b[38;2;245;158;11m';
@@ -32,7 +34,7 @@ function showBanner() {
32
34
 
33
35
  ${PURPLE} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
34
36
 
35
- ${PURPLE}${BOLD} ▄▀█ █ █ █▀█ █▀█ █▀█${RESET} ${DIM}OS v1.0${RESET}
37
+ ${PURPLE}${BOLD} ▄▀█ █ █ █▀█ █▀█ █▀█${RESET} ${DIM}OS v${PKG_VERSION}${RESET}
36
38
  ${PURPLE}${BOLD} █▀█ █▄▄█ █▀▄ █▄█ ▀▀█${RESET}
37
39
 
38
40
  ${DIM} Sistema Operacional de IA para Experts${RESET}
@@ -53,6 +55,131 @@ function error(msg) { console.log(` ${PURPLE}✗${RESET} ${msg}`); }
53
55
 
54
56
  function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
55
57
 
58
+ // Pergunta sim/nao no terminal. Funciona em TTY e com stdin encadeado (pipe).
59
+ // Se o stdin estiver fechado (automatos/CI), question() nunca resolve — por isso
60
+ // a corrida com o evento 'close': EOF vira resposta vazia, ou seja, "nao".
61
+ async function askYesNo(question) {
62
+ const readline = require('node:readline/promises');
63
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
64
+ try {
65
+ const closed = new Promise(resolve => rl.once('close', () => resolve('')));
66
+ const answer = String(await Promise.race([rl.question(question), closed])).trim().toLowerCase();
67
+ return answer === 's' || answer === 'sim' || answer === 'y' || answer === 'yes';
68
+ } catch {
69
+ return false;
70
+ } finally {
71
+ rl.close();
72
+ }
73
+ }
74
+
75
+ // ─── PROTECAO DE SEGREDOS (gitignore canonico) ───────────
76
+ // Gerado por codigo, nao copiado de arquivo: o tarball do npm nem sempre
77
+ // preserva .gitignore, e o merge preserva as linhas proprias do expert.
78
+ const GITIGNORE_PROTECTIONS = [
79
+ ['Segredos — NUNCA sobem pro GitHub', ['.env', '.env.local', '.env.*.local', '.npmrc', 'business/vault/', '*.key', '*.pem']],
80
+ ['Runtime — se recria sozinho em cada maquina', ['node_modules/', '.auroq/', '.synapse/sessions/', '.tmp/', '*.tmp', '*.log']],
81
+ ['Skills do Codex — geradas por maquina', ['.agents/skills/']],
82
+ ['Sistema operacional', ['.DS_Store', 'Thumbs.db']],
83
+ ['Midia pesada — fica no Drive, nao no repo', ['*.png', '*.jpeg', '*.jpg', '*.mp4', '*.mov', '*.mp3', '*.wav']],
84
+ ];
85
+
86
+ async function ensureGitignore(targetDir) {
87
+ const giPath = path.join(targetDir, '.gitignore');
88
+ const existing = (await fs.pathExists(giPath)) ? await fs.readFile(giPath, 'utf8') : '';
89
+ const have = new Set(existing.split('\n').map(l => l.trim()).filter(Boolean));
90
+ const missingBlocks = [];
91
+ for (const [comment, lines] of GITIGNORE_PROTECTIONS) {
92
+ const missing = lines.filter(l => !have.has(l));
93
+ if (missing.length) missingBlocks.push(`# ${comment}\n${missing.join('\n')}`);
94
+ }
95
+ if (!missingBlocks.length) return [];
96
+ const base = existing.trim().length ? existing.replace(/\s*$/, '\n\n') : '';
97
+ const header = '# ── Protecoes do Auroq OS (adicionadas automaticamente) ──\n';
98
+ await fs.writeFile(giPath, base + header + missingBlocks.join('\n\n') + '\n');
99
+ return missingBlocks.flatMap(b => b.split('\n').filter(l => l && !l.startsWith('#')));
100
+ }
101
+
102
+ // Tira do controle de versao segredos que ja foram rastreados (ficam no disco).
103
+ async function untrackSecrets(targetDir) {
104
+ if (!(await fs.pathExists(path.join(targetDir, '.git')))) return [];
105
+ let tracked = [];
106
+ try {
107
+ const out = execFileSync('git', ['ls-files', '--', 'business/vault', '.env', '.env.local', '*.key', '*.pem', '.npmrc'], { cwd: targetDir, encoding: 'utf8' });
108
+ tracked = out.split('\n').map(s => s.trim()).filter(Boolean);
109
+ } catch {
110
+ return [];
111
+ }
112
+ if (!tracked.length) return [];
113
+ try {
114
+ execFileSync('git', ['rm', '-r', '--cached', '--quiet', '--', ...tracked], { cwd: targetDir, stdio: 'pipe' });
115
+ } catch {
116
+ return [];
117
+ }
118
+ return tracked;
119
+ }
120
+
121
+ async function applySecretProtections(targetDir) {
122
+ const added = await ensureGitignore(targetDir);
123
+ if (added.length) {
124
+ success(`Protecoes adicionadas ao .gitignore (${added.length} regras: vault, .env, runtime, midia)`);
125
+ } else {
126
+ success('.gitignore ja protege segredos e runtime');
127
+ }
128
+ const untracked = await untrackSecrets(targetDir);
129
+ if (untracked.length) {
130
+ warn(`${untracked.length} arquivo(s) sensivel(is) removido(s) do controle de versao (continuam no seu disco):`);
131
+ for (const f of untracked.slice(0, 8)) log(`${DIM} - ${f}${RESET}`);
132
+ if (untracked.length > 8) log(`${DIM} ... e mais ${untracked.length - 8}${RESET}`);
133
+ warn('No proximo commit isso vira permanente.');
134
+ let hasRemote = false;
135
+ try { hasRemote = execFileSync('git', ['remote'], { cwd: targetDir, encoding: 'utf8' }).trim().length > 0; } catch { /* sem git */ }
136
+ if (hasRemote) {
137
+ warn(`${GOLD}IMPORTANTE: esses arquivos podem ja ter subido pro GitHub em commits antigos.${RESET}`);
138
+ warn(`${GOLD}Troque as chaves que estavam neles — peca ajuda ao Ops: "minhas chaves do vault${RESET}`);
139
+ warn(`${GOLD}podem ter vazado no git, me ajuda a trocar e limpar".${RESET}`);
140
+ }
141
+ }
142
+ return { added, untracked };
143
+ }
144
+
145
+ // ─── HEALTH CHECK (compartilhado por init e clone) ───────
146
+ const HEALTH_CHECKS = [
147
+ ['.auroq-core/constitution.md', 'Constitution'],
148
+ ['.claude/CLAUDE.md', 'CLAUDE.md'],
149
+ ['.claude/hooks/synapse-engine.cjs', 'Synapse Hook'],
150
+ ['agents/companion/agents/companion.md', 'Companion'],
151
+ ['agents/organizer/agents/organizer.md', 'Organizer'],
152
+ ['.claude/commands/AuroqOS/agents/ops.md', 'Ops'],
153
+ ['agents/squad-forge/agents/forge-chief.md', 'Squad Forge'],
154
+ ['agents/mind-forge/agents/forge-chief.md', 'Mind Forge'],
155
+ ['agents/worker-forge/agents/worker-chief.md', 'Worker Forge'],
156
+ ['agents/clone-forge/agents/clone-forge-chief.md', 'Clone Forge'],
157
+ ['agents/etlmaker/agents/etl-chief.md', 'ETLmaker'],
158
+ ['business/cockpit.md', 'Cockpit'],
159
+ ['.synapse/manifest', 'Synapse Manifest'],
160
+ ['AGENTS.md', 'Codex AGENTS.md'],
161
+ ['.agents/skills/companion/SKILL.md', 'Codex Companion'],
162
+ ['.agents/skills/ops/SKILL.md', 'Codex Ops'],
163
+ ['scripts/validate-hybrid.mjs', 'Validador hibrido'],
164
+ ];
165
+
166
+ async function runHealthChecks(targetDir) {
167
+ let passed = 0;
168
+ for (const [file, label] of HEALTH_CHECKS) {
169
+ if (await fs.pathExists(path.join(targetDir, file))) {
170
+ passed++;
171
+ } else {
172
+ warn(`${label} nao encontrado`);
173
+ }
174
+ }
175
+ if (passed === HEALTH_CHECKS.length) {
176
+ success(`${passed}/${HEALTH_CHECKS.length} verificacoes OK`);
177
+ } else {
178
+ warn(`${passed}/${HEALTH_CHECKS.length} verificacoes OK — rode *bootstrap pra corrigir`);
179
+ }
180
+ return { passed, total: HEALTH_CHECKS.length };
181
+ }
182
+
56
183
  // ─── INSTALACAO ──────────────────────────────────────────
57
184
  async function init() {
58
185
  showBanner();
@@ -78,6 +205,27 @@ async function init() {
78
205
  process.exit(1);
79
206
  }
80
207
 
208
+ // ─── GUARDRAIL: segunda maquina usa clone, nao init
209
+ // So pergunta em instalacao NOVA (pasta sem .auroq-core) — update/reinstall pula direto.
210
+ const isNewInstall = !(await fs.pathExists(path.join(targetDir, '.auroq-core')));
211
+ if (isNewInstall && process.env.AUROQ_INIT_MODE !== 'novo') {
212
+ const jaUsa = await askYesNo(` Voce JA usa o Auroq OS em outra maquina e quer continuar o MESMO negocio aqui? ${DIM}(s/N)${RESET} `);
213
+ if (jaUsa) {
214
+ log('');
215
+ log(`${BOLD}Entao o caminho certo NAO e instalar do zero — e clonar o que ja existe.${RESET}`);
216
+ log('');
217
+ log('O seu negocio ja vive no GitHub (o Ops fez isso no Bootstrap 1).');
218
+ log('Instalar do zero aqui criaria um segundo Auroq desconectado do primeiro.');
219
+ log('');
220
+ log(`Rode: ${CYAN}npx auroq-os clone${RESET}`);
221
+ log('');
222
+ log(`${DIM}Ele baixa o seu negocio inteiro do GitHub — sistema, memoria e documentos —${RESET}`);
223
+ log(`${DIM}e deixa tudo pronto. Depois e so reconectar o cofre com *conectar-1password.${RESET}`);
224
+ log('');
225
+ process.exit(0);
226
+ }
227
+ }
228
+
81
229
  log(`${DIM}Instalando em: ${targetDir}${RESET}\n`);
82
230
 
83
231
  // ─── Fase 1: Verificar pre-requisitos
@@ -256,7 +404,8 @@ async function init() {
256
404
  'docs/knowledge/expert-business/publico-alvo.md',
257
405
 
258
406
  // Root
259
- '.gitignore',
407
+ // (.gitignore NAO entra aqui: e gerado por codigo em applySecretProtections —
408
+ // o tarball do npm nem sempre o preserva, e a copia cega apagaria linhas do expert)
260
409
  '.env.example',
261
410
  'README.md',
262
411
 
@@ -456,43 +605,15 @@ async function init() {
456
605
  success('Git ja inicializado');
457
606
  }
458
607
 
608
+ // Protecoes de segredo: .gitignore canonico + destraquear o que nao pode viajar.
609
+ // Roda em toda instalacao E em todo update (o update reexecuta o init) — e assim
610
+ // que alunos com instalacao antiga sao migrados automaticamente.
611
+ step('Protegendo segredos...');
612
+ await applySecretProtections(targetDir);
613
+
459
614
  // ─── Fase 7: Health check rapido
460
615
  step('Verificando integridade...');
461
-
462
- const checks = [
463
- ['.auroq-core/constitution.md', 'Constitution'],
464
- ['.claude/CLAUDE.md', 'CLAUDE.md'],
465
- ['.claude/hooks/synapse-engine.cjs', 'Synapse Hook'],
466
- ['agents/companion/agents/companion.md', 'Companion'],
467
- ['agents/organizer/agents/organizer.md', 'Organizer'],
468
- ['.claude/commands/AuroqOS/agents/ops.md', 'Ops'],
469
- ['agents/squad-forge/agents/forge-chief.md', 'Squad Forge'],
470
- ['agents/mind-forge/agents/forge-chief.md', 'Mind Forge'],
471
- ['agents/worker-forge/agents/worker-chief.md', 'Worker Forge'],
472
- ['agents/clone-forge/agents/clone-forge-chief.md', 'Clone Forge'],
473
- ['agents/etlmaker/agents/etl-chief.md', 'ETLmaker'],
474
- ['business/cockpit.md', 'Cockpit'],
475
- ['.synapse/manifest', 'Synapse Manifest'],
476
- ['AGENTS.md', 'Codex AGENTS.md'],
477
- ['.agents/skills/companion/SKILL.md', 'Codex Companion'],
478
- ['.agents/skills/ops/SKILL.md', 'Codex Ops'],
479
- ['scripts/validate-hybrid.mjs', 'Validador hibrido'],
480
- ];
481
-
482
- let passed = 0;
483
- for (const [file, label] of checks) {
484
- if (await fs.pathExists(path.join(targetDir, file))) {
485
- passed++;
486
- } else {
487
- warn(`${label} nao encontrado`);
488
- }
489
- }
490
-
491
- if (passed === checks.length) {
492
- success(`${passed}/${checks.length} verificacoes OK`);
493
- } else {
494
- warn(`${passed}/${checks.length} verificacoes OK — rode *bootstrap pra corrigir`);
495
- }
616
+ await runHealthChecks(targetDir);
496
617
 
497
618
  // ─── Resultado final
498
619
  console.log(`
@@ -527,11 +648,182 @@ ${DIM} Meta Squads (criadores de agentes):${RESET}
527
648
  ${DIM} Claude Code e Codex sao runtimes oficiais. Escolha um por sessao; ambos usam os mesmos agentes e arquivos.${RESET}
528
649
 
529
650
  ${PURPLE}${BOLD} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
530
- ${DIM} Auroq OS v2.1.0 — Sistema Operacional de IA para Experts${RESET}
651
+ ${DIM} Auroq OS v${PKG_VERSION} — Sistema Operacional de IA para Experts${RESET}
531
652
  ${DIM} "Tu aumentaste o meu poder como do boi selvagem." — Sl 92:10${RESET}
532
653
  `);
533
654
  }
534
655
 
656
+ // ─── CLONE (segunda maquina / colaborador) ───────────────
657
+ // O Auroq nao mora no computador — mora no GitHub. Clonar JA E a instalacao:
658
+ // o sistema vem inteiro no clone. Este comando so completa o que nao viaja
659
+ // (dependencias, skills do Codex) e confere a integridade.
660
+ async function clone(repoArg) {
661
+ showBanner();
662
+ await sleep(300);
663
+
664
+ const cwd = process.cwd();
665
+
666
+ if (await fs.pathExists(path.join(cwd, '.auroq-core'))) {
667
+ error('Voce ja esta DENTRO de um projeto Auroq.');
668
+ error('Va pra pasta onde quer criar a copia (ex: cd ~/Documents) e rode de novo.');
669
+ process.exit(1);
670
+ }
671
+
672
+ log(`${DIM}Clonando o seu negocio para: ${cwd}${RESET}\n`);
673
+
674
+ // ─── Fase 1: Pre-requisitos
675
+ step('Verificando pre-requisitos...');
676
+ try {
677
+ execSync('git --version', { encoding: 'utf8', stdio: 'pipe' });
678
+ success('Git instalado');
679
+ } catch {
680
+ error('Git nao encontrado. Instale git primeiro.');
681
+ process.exit(1);
682
+ }
683
+
684
+ // ─── Fase 1b: Gate de acesso (mesmo do init)
685
+ step('Verificando acesso...');
686
+ const testAuthBypass = process.env.NODE_ENV === 'test' && process.env.AUROQ_SKIP_AUTH === '1';
687
+ if (testAuthBypass) {
688
+ success('Gate de acesso ignorado em ambiente de teste');
689
+ } else {
690
+ try {
691
+ await auth.getValidSession();
692
+ } catch (e) {
693
+ error(`Falha na autenticacao: ${e.message}`);
694
+ process.exit(1);
695
+ }
696
+ }
697
+
698
+ // ─── Fase 2: Resolver o repositorio
699
+ let repoRef = repoArg;
700
+ if (!repoRef) {
701
+ step('Localizando o seu negocio no GitHub...');
702
+ try {
703
+ execSync('gh --version', { encoding: 'utf8', stdio: 'pipe' });
704
+ } catch {
705
+ error('GitHub CLI (gh) nao encontrado e nenhum repositorio informado.');
706
+ error('');
707
+ error('Duas opcoes:');
708
+ error(` 1. Instale o gh (https://cli.github.com) e rode de novo: ${CYAN}npx auroq-os clone${RESET}`);
709
+ error(` 2. Ou informe o endereco direto: ${CYAN}npx auroq-os clone https://github.com/SEU-USUARIO/SEU-REPO.git${RESET}`);
710
+ process.exit(1);
711
+ }
712
+ try {
713
+ execSync('gh auth status', { encoding: 'utf8', stdio: 'pipe' });
714
+ success('GitHub conectado');
715
+ } catch {
716
+ warn('GitHub nao conectado nesta maquina — abrindo o login...');
717
+ try {
718
+ execSync('gh auth login', { stdio: 'inherit' });
719
+ } catch {
720
+ error('Login no GitHub falhou. Rode "gh auth login" e tente de novo.');
721
+ process.exit(1);
722
+ }
723
+ }
724
+ let repos = [];
725
+ try {
726
+ const out = execSync('gh repo list --json nameWithOwner,updatedAt --limit 30', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
727
+ repos = JSON.parse(out);
728
+ } catch { /* lista vazia tratada abaixo */ }
729
+ if (!repos.length) {
730
+ error('Nenhum repositorio encontrado na sua conta do GitHub.');
731
+ error(`Informe o endereco direto: ${CYAN}npx auroq-os clone https://github.com/SEU-USUARIO/SEU-REPO.git${RESET}`);
732
+ process.exit(1);
733
+ }
734
+ const prompts = require('prompts');
735
+ const resp = await prompts({
736
+ type: 'select',
737
+ name: 'repo',
738
+ message: 'Qual repositorio e o seu negocio?',
739
+ choices: repos.map(r => ({ title: r.nameWithOwner, value: r.nameWithOwner })),
740
+ }, { onCancel: () => { error('Cancelado.'); process.exit(1); } });
741
+ repoRef = resp.repo;
742
+ }
743
+
744
+ // ─── Fase 3: Clonar
745
+ step(`Baixando o negocio inteiro (${repoRef})...`);
746
+ const destName = path.basename(String(repoRef).replace(/[\\/]+$/, '')).replace(/\.git$/, '');
747
+ const destDir = path.join(cwd, destName);
748
+ if (await fs.pathExists(destDir)) {
749
+ error(`A pasta "${destName}" ja existe aqui. Entre nela (cd ${destName}) ou rode em outro lugar.`);
750
+ process.exit(1);
751
+ }
752
+ const isOwnerRepo = /^[\w.-]+\/[\w.-]+$/.test(String(repoRef));
753
+ try {
754
+ if (isOwnerRepo) {
755
+ execFileSync('gh', ['repo', 'clone', String(repoRef)], { cwd, stdio: 'inherit' });
756
+ } else {
757
+ execFileSync('git', ['clone', String(repoRef), destName], { cwd, stdio: 'inherit' });
758
+ }
759
+ success('Negocio baixado do GitHub');
760
+ } catch {
761
+ error('Falha ao clonar. Confira o endereco e o seu acesso ao repositorio.');
762
+ process.exit(1);
763
+ }
764
+
765
+ // ─── Fase 4: Reconhecer o projeto
766
+ if (await fs.pathExists(path.join(destDir, '.auroq-core'))) {
767
+ success('Projeto Auroq reconhecido — o sistema veio inteiro no clone');
768
+ } else {
769
+ warn('Este repositorio nao parece um projeto Auroq (.auroq-core ausente).');
770
+ warn('Se for o repo errado, apague a pasta e rode de novo com o repo certo.');
771
+ }
772
+
773
+ // ─── Fase 5: Protecoes de segredo
774
+ step('Protegendo segredos...');
775
+ await applySecretProtections(destDir);
776
+
777
+ // ─── Fase 6: Dependencias (nao viajam no git — de proposito)
778
+ step('Instalando dependencias...');
779
+ try {
780
+ execSync('npm install --silent', { cwd: destDir, stdio: 'pipe' });
781
+ success('Dependencias instaladas');
782
+ } catch {
783
+ warn('npm install falhou — entre na pasta e rode "npm install" manualmente');
784
+ }
785
+
786
+ // ─── Fase 7: Skills do Codex (geradas por maquina)
787
+ if (await fs.pathExists(path.join(destDir, 'scripts', 'sync-codex-skills.mjs'))) {
788
+ step('Configurando Codex CLI...');
789
+ try {
790
+ execSync('node scripts/sync-codex-skills.mjs --clean', { cwd: destDir, stdio: 'pipe' });
791
+ success('Skills locais do Codex regeneradas');
792
+ } catch {
793
+ warn('Sync de skills do Codex falhou — rode "npx auroq-os sync-codex" depois');
794
+ }
795
+ }
796
+
797
+ // ─── Fase 8: Health check
798
+ step('Verificando integridade...');
799
+ await runHealthChecks(destDir);
800
+
801
+ // ─── Resultado final
802
+ console.log(`
803
+ ${PURPLE}${BOLD} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
804
+
805
+ ${GREEN}${BOLD} Negocio clonado com sucesso. Esta maquina esta pronta.${RESET}
806
+
807
+ ${DIM} Uma vez so, nesta maquina:${RESET}
808
+
809
+ ${CYAN}cd ${destName}${RESET}
810
+ ${CYAN}claude${RESET} ${DIM}ou${RESET} ${CYAN}codex${RESET}
811
+ ${CYAN}/AuroqOS:agents:ops${RESET}
812
+ ${CYAN}*conectar-1password${RESET} ${DIM}— reconectar o cofre de senhas${RESET}
813
+ ${DIM}(se pedir login do sistema: ${RESET}${CYAN}npx auroq-os login${RESET}${DIM})${RESET}
814
+
815
+ ${DIM} Ritual de todo dia, em toda maquina:${RESET}
816
+
817
+ ${GOLD}Sentou${RESET} → ${CYAN}*sync${RESET} ${DIM}— puxa o que mudou nas outras maquinas${RESET}
818
+ ${GOLD}Levantou${RESET} → ${CYAN}*commit${RESET} + ${CYAN}*push${RESET} ${DIM}— entrega o seu trabalho pro GitHub${RESET}
819
+
820
+ ${DIM} Nunca levante da maquina com trabalho nao entregue.${RESET}
821
+
822
+ ${PURPLE}${BOLD} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
823
+ ${DIM} Auroq OS v${PKG_VERSION} — Sistema Operacional de IA para Experts${RESET}
824
+ `);
825
+ }
826
+
535
827
  // ─── CLI ─────────────────────────────────────────────────
536
828
  const command = process.argv[2];
537
829
 
@@ -540,6 +832,19 @@ if (command === 'init' || command === 'install') {
540
832
  error(`Falha na instalacao: ${err.message}`);
541
833
  process.exit(1);
542
834
  });
835
+ } else if (command === 'clone') {
836
+ clone(process.argv[3]).catch(err => {
837
+ error(`Falha ao clonar: ${err.message}`);
838
+ process.exit(1);
839
+ });
840
+ } else if (command === 'fix-gitignore') {
841
+ (async () => {
842
+ step('Protegendo segredos...');
843
+ await applySecretProtections(process.cwd());
844
+ })().catch(err => {
845
+ error(`Falha: ${err.message}`);
846
+ process.exit(1);
847
+ });
543
848
  } else if (command === 'login') {
544
849
  auth.interactiveLogin().catch(err => {
545
850
  error(`Falha no login: ${err.message}`);
@@ -594,7 +899,9 @@ if (command === 'init' || command === 'install') {
594
899
  } else {
595
900
  showBanner();
596
901
  log(`${BOLD}Comandos disponiveis:${RESET}`);
597
- log(` ${CYAN}init${RESET} Instalar Auroq OS no diretorio atual`);
902
+ log(` ${CYAN}init${RESET} Instalar Auroq OS no diretorio atual (primeira maquina)`);
903
+ log(` ${CYAN}clone${RESET} Continuar o seu negocio NESTA maquina (segunda maquina / colaborador)`);
904
+ log(` ${CYAN}fix-gitignore${RESET} Garantir protecoes de segredo no .gitignore (vault, .env)`);
598
905
  log(` ${CYAN}login${RESET} Autenticar com email + senha da Mentoria Arcane`);
599
906
  log(` ${CYAN}logout${RESET} Encerrar sessao local`);
600
907
  log(` ${CYAN}whoami${RESET} Mostrar usuario autenticado`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auroq-os",
3
- "version": "2.1.5",
3
+ "version": "2.2.0",
4
4
  "description": "Auroq OS — Sistema Operacional de IA para Experts",
5
5
  "bin": {
6
6
  "auroq-os": "bin/auroq-os.js"