auroq-os 2.1.6 → 2.2.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/.claude/commands/AuroqOS/agents/ops.md +92 -9
- package/README.md +23 -1
- package/bin/auroq-os.js +338 -40
- package/package.json +1 -1
|
@@ -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.
|
|
39
|
-
4.
|
|
40
|
-
5.
|
|
41
|
-
6.
|
|
42
|
-
7. Atualizar o
|
|
43
|
-
8.
|
|
44
|
-
9.
|
|
45
|
-
10.
|
|
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,63 @@ 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
|
+
- Colaborador NAO precisa ser aluno da mentoria (politica oficial, 05/08/2026). O acesso dele e o convite do GitHub; o `npx auroq-os clone` nao pede login de aluno
|
|
219
|
+
- Quem atualiza o SISTEMA e o dono (o *update-auroq exige aluno ativo) — o colaborador recebe as atualizacoes automaticamente via *sync, porque o update vira commit no repo
|
|
220
|
+
- 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
|
|
221
|
+
- Credenciais de squad: cofre separado no 1Password (ex: "Equipe") com SO o que ele precisa — nunca o cofre pessoal do expert
|
|
222
|
+
- 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
|
|
223
|
+
- Dividir trabalho por AREA (um no conteudo, outro no trafego), nao por arquivo — conflito so nasce quando dois mexem no mesmo arquivo
|
|
224
|
+
- Quando a pessoa sair: remover do GitHub, tirar do cofre, revogar tokens que ela usava
|
|
225
|
+
|
|
226
|
+
**Arquivo pesado (video, imagem grande, audio):**
|
|
227
|
+
- 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
|
|
228
|
+
- O .gitignore canonico ja bloqueia midia nova; midia ja versionada antes continua no historico (nao remover sem o expert pedir)
|
|
229
|
+
|
|
169
230
|
### *update-auroq
|
|
170
231
|
Atualizar o Auroq OS com a versao mais recente do framework via npm.
|
|
171
232
|
O expert so precisa pedir "atualiza o sistema" — Ops faz o resto.
|
|
@@ -213,8 +274,9 @@ A validacao e ONLINE e obrigatoria, sem fallback offline — e a mesma trava do
|
|
|
213
274
|
- `AGENTS.md` — regras e contexto do Codex
|
|
214
275
|
- `scripts/sync-codex-skills.mjs` e `scripts/validate-hybrid.mjs` — ponte Codex
|
|
215
276
|
- `.synapse/` — manifest, constitution, global, context
|
|
216
|
-
- `bin/` — installer
|
|
277
|
+
- `bin/` — installer (traz comandos novos: clone, fix-gitignore)
|
|
217
278
|
- `package.json` — dependencias
|
|
279
|
+
- `.gitignore` — protecoes de seguranca via `fix-gitignore` (MERGE: adiciona o que falta, preserva as linhas do expert — NUNCA sobrescrever o arquivo inteiro)
|
|
218
280
|
- `agents/squad-forge/` — meta squad oficial
|
|
219
281
|
- `agents/mind-forge/` — meta squad oficial
|
|
220
282
|
- `agents/worker-forge/` — meta squad oficial
|
|
@@ -245,6 +307,7 @@ Para cada arquivo da versao nova:
|
|
|
245
307
|
|
|
246
308
|
**Passo 5 — Pos-atualizacao**
|
|
247
309
|
1. `npm install` — atualizar dependencias
|
|
310
|
+
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
311
|
2. Confirmar que `.auroq-core/core-config.yaml` recebeu a nova `project.version` (nao alterar a versao do app do expert)
|
|
249
312
|
3. Rodar `node scripts/sync-codex-skills.mjs --clean` e depois `--check`
|
|
250
313
|
4. Limpar temp: `rm -rf /tmp/auroq-update/`
|
|
@@ -1018,6 +1081,22 @@ Conecta o cofre 1Password ao Auroq. O expert NAO abre terminal e NAO digita coma
|
|
|
1018
1081
|
- 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.
|
|
1019
1082
|
- 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.
|
|
1020
1083
|
|
|
1084
|
+
**Greeting (primeira fala ao acionar — mostrar SEMPRE, depois seguir pro passo 1):**
|
|
1085
|
+
|
|
1086
|
+
```
|
|
1087
|
+
=== CONECTAR 1PASSWORD ===
|
|
1088
|
+
|
|
1089
|
+
Vou ligar teu cofre 1Password ao Auroq. O que isso faz: conecto o
|
|
1090
|
+
1Password CLI (instalo se faltar), valido a conexao com seguranca e
|
|
1091
|
+
deixo o sistema guardando tuas senhas e tokens no cofre — voce nunca
|
|
1092
|
+
mais cola segredo no chat nem em arquivo solto.
|
|
1093
|
+
|
|
1094
|
+
Voce nao abre terminal nem digita comando. Sua unica tarefa e copiar
|
|
1095
|
+
um codigo. Eu faco o resto.
|
|
1096
|
+
|
|
1097
|
+
Deixa eu ver como teu cofre esta agora.
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1021
1100
|
**Fluxo:**
|
|
1022
1101
|
|
|
1023
1102
|
1. **Checar se ja esta conectado** (sem expor segredos):
|
|
@@ -1649,11 +1728,15 @@ CONFIGURACAO:
|
|
|
1649
1728
|
*yolo Trocar modo de permissao (auto/manual)
|
|
1650
1729
|
|
|
1651
1730
|
GITHUB:
|
|
1731
|
+
*sync Puxar atualizacoes do GitHub (inicio de sessao)
|
|
1652
1732
|
*pr Criar Pull Request
|
|
1653
1733
|
*status Status do git + projetos
|
|
1654
1734
|
|
|
1655
1735
|
DICA: *commit e o comando mais importante. Use no final de cada sessao.
|
|
1656
1736
|
"Commit e o botao salvar do sistema."
|
|
1737
|
+
|
|
1738
|
+
RITUAL MULTI-MAQUINA: Sentou → *sync · Levantou → *commit + *push
|
|
1739
|
+
Segunda maquina ou colaborador? O caminho e "npx auroq-os clone" (nunca init).
|
|
1657
1740
|
```
|
|
1658
1741
|
|
|
1659
1742
|
### *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,26 @@ 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. **Colaborador nao precisa ser
|
|
76
|
+
aluno**: o acesso dele e o convite do GitHub (o `clone` nao pede login); quem atualiza
|
|
77
|
+
o sistema e o dono, e o colaborador recebe as atualizacoes via `*sync`.
|
|
78
|
+
|
|
57
79
|
## Estrutura
|
|
58
80
|
|
|
59
81
|
```
|
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
|
|
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
|
-
|
|
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,173 @@ ${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
|
|
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
|
+
// Sem gate de aluno aqui — decisao de produto (05/08/2026): colaborador NAO
|
|
685
|
+
// precisa ser aluno. O gate real do clone e o convite do GitHub (repo privado);
|
|
686
|
+
// um git clone puro ja entregaria o mesmo conteudo. Os gates de aluno ficam
|
|
687
|
+
// onde ha valor do framework: init (criar do zero) e *update-auroq (atualizar).
|
|
688
|
+
|
|
689
|
+
// ─── Fase 2: Resolver o repositorio
|
|
690
|
+
let repoRef = repoArg;
|
|
691
|
+
if (!repoRef) {
|
|
692
|
+
step('Localizando o seu negocio no GitHub...');
|
|
693
|
+
try {
|
|
694
|
+
execSync('gh --version', { encoding: 'utf8', stdio: 'pipe' });
|
|
695
|
+
} catch {
|
|
696
|
+
error('GitHub CLI (gh) nao encontrado e nenhum repositorio informado.');
|
|
697
|
+
error('');
|
|
698
|
+
error('Duas opcoes:');
|
|
699
|
+
error(` 1. Instale o gh (https://cli.github.com) e rode de novo: ${CYAN}npx auroq-os clone${RESET}`);
|
|
700
|
+
error(` 2. Ou informe o endereco direto: ${CYAN}npx auroq-os clone https://github.com/SEU-USUARIO/SEU-REPO.git${RESET}`);
|
|
701
|
+
process.exit(1);
|
|
702
|
+
}
|
|
703
|
+
try {
|
|
704
|
+
execSync('gh auth status', { encoding: 'utf8', stdio: 'pipe' });
|
|
705
|
+
success('GitHub conectado');
|
|
706
|
+
} catch {
|
|
707
|
+
warn('GitHub nao conectado nesta maquina — abrindo o login...');
|
|
708
|
+
try {
|
|
709
|
+
execSync('gh auth login', { stdio: 'inherit' });
|
|
710
|
+
} catch {
|
|
711
|
+
error('Login no GitHub falhou. Rode "gh auth login" e tente de novo.');
|
|
712
|
+
process.exit(1);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
let repos = [];
|
|
716
|
+
try {
|
|
717
|
+
const out = execSync('gh repo list --json nameWithOwner,updatedAt --limit 30', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
718
|
+
repos = JSON.parse(out);
|
|
719
|
+
} catch { /* lista vazia tratada abaixo */ }
|
|
720
|
+
if (!repos.length) {
|
|
721
|
+
error('Nenhum repositorio encontrado na sua conta do GitHub.');
|
|
722
|
+
error(`Informe o endereco direto: ${CYAN}npx auroq-os clone https://github.com/SEU-USUARIO/SEU-REPO.git${RESET}`);
|
|
723
|
+
process.exit(1);
|
|
724
|
+
}
|
|
725
|
+
const prompts = require('prompts');
|
|
726
|
+
const resp = await prompts({
|
|
727
|
+
type: 'select',
|
|
728
|
+
name: 'repo',
|
|
729
|
+
message: 'Qual repositorio e o seu negocio?',
|
|
730
|
+
choices: repos.map(r => ({ title: r.nameWithOwner, value: r.nameWithOwner })),
|
|
731
|
+
}, { onCancel: () => { error('Cancelado.'); process.exit(1); } });
|
|
732
|
+
repoRef = resp.repo;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// ─── Fase 3: Clonar
|
|
736
|
+
step(`Baixando o negocio inteiro (${repoRef})...`);
|
|
737
|
+
const destName = path.basename(String(repoRef).replace(/[\\/]+$/, '')).replace(/\.git$/, '');
|
|
738
|
+
const destDir = path.join(cwd, destName);
|
|
739
|
+
if (await fs.pathExists(destDir)) {
|
|
740
|
+
error(`A pasta "${destName}" ja existe aqui. Entre nela (cd ${destName}) ou rode em outro lugar.`);
|
|
741
|
+
process.exit(1);
|
|
742
|
+
}
|
|
743
|
+
const isOwnerRepo = /^[\w.-]+\/[\w.-]+$/.test(String(repoRef));
|
|
744
|
+
try {
|
|
745
|
+
if (isOwnerRepo) {
|
|
746
|
+
execFileSync('gh', ['repo', 'clone', String(repoRef)], { cwd, stdio: 'inherit' });
|
|
747
|
+
} else {
|
|
748
|
+
execFileSync('git', ['clone', String(repoRef), destName], { cwd, stdio: 'inherit' });
|
|
749
|
+
}
|
|
750
|
+
success('Negocio baixado do GitHub');
|
|
751
|
+
} catch {
|
|
752
|
+
error('Falha ao clonar. Confira o endereco e o seu acesso ao repositorio.');
|
|
753
|
+
process.exit(1);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// ─── Fase 4: Reconhecer o projeto
|
|
757
|
+
if (await fs.pathExists(path.join(destDir, '.auroq-core'))) {
|
|
758
|
+
success('Projeto Auroq reconhecido — o sistema veio inteiro no clone');
|
|
759
|
+
} else {
|
|
760
|
+
warn('Este repositorio nao parece um projeto Auroq (.auroq-core ausente).');
|
|
761
|
+
warn('Se for o repo errado, apague a pasta e rode de novo com o repo certo.');
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// ─── Fase 5: Protecoes de segredo
|
|
765
|
+
step('Protegendo segredos...');
|
|
766
|
+
await applySecretProtections(destDir);
|
|
767
|
+
|
|
768
|
+
// ─── Fase 6: Dependencias (nao viajam no git — de proposito)
|
|
769
|
+
step('Instalando dependencias...');
|
|
770
|
+
try {
|
|
771
|
+
execSync('npm install --silent', { cwd: destDir, stdio: 'pipe' });
|
|
772
|
+
success('Dependencias instaladas');
|
|
773
|
+
} catch {
|
|
774
|
+
warn('npm install falhou — entre na pasta e rode "npm install" manualmente');
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// ─── Fase 7: Skills do Codex (geradas por maquina)
|
|
778
|
+
if (await fs.pathExists(path.join(destDir, 'scripts', 'sync-codex-skills.mjs'))) {
|
|
779
|
+
step('Configurando Codex CLI...');
|
|
780
|
+
try {
|
|
781
|
+
execSync('node scripts/sync-codex-skills.mjs --clean', { cwd: destDir, stdio: 'pipe' });
|
|
782
|
+
success('Skills locais do Codex regeneradas');
|
|
783
|
+
} catch {
|
|
784
|
+
warn('Sync de skills do Codex falhou — rode "npx auroq-os sync-codex" depois');
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// ─── Fase 8: Health check
|
|
789
|
+
step('Verificando integridade...');
|
|
790
|
+
await runHealthChecks(destDir);
|
|
791
|
+
|
|
792
|
+
// ─── Resultado final
|
|
793
|
+
console.log(`
|
|
794
|
+
${PURPLE}${BOLD} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
|
|
795
|
+
|
|
796
|
+
${GREEN}${BOLD} Negocio clonado com sucesso. Esta maquina esta pronta.${RESET}
|
|
797
|
+
|
|
798
|
+
${DIM} Uma vez so, nesta maquina:${RESET}
|
|
799
|
+
|
|
800
|
+
${CYAN}cd ${destName}${RESET}
|
|
801
|
+
${CYAN}claude${RESET} ${DIM}ou${RESET} ${CYAN}codex${RESET}
|
|
802
|
+
${CYAN}/AuroqOS:agents:ops${RESET}
|
|
803
|
+
${CYAN}*conectar-1password${RESET} ${DIM}— reconectar o cofre de senhas${RESET}
|
|
804
|
+
${DIM}(dono do negocio: se o sistema pedir login em algum momento, ${RESET}${CYAN}npx auroq-os login${RESET}${DIM})${RESET}
|
|
805
|
+
|
|
806
|
+
${DIM} Ritual de todo dia, em toda maquina:${RESET}
|
|
807
|
+
|
|
808
|
+
${GOLD}Sentou${RESET} → ${CYAN}*sync${RESET} ${DIM}— puxa o que mudou nas outras maquinas${RESET}
|
|
809
|
+
${GOLD}Levantou${RESET} → ${CYAN}*commit${RESET} + ${CYAN}*push${RESET} ${DIM}— entrega o seu trabalho pro GitHub${RESET}
|
|
810
|
+
|
|
811
|
+
${DIM} Nunca levante da maquina com trabalho nao entregue.${RESET}
|
|
812
|
+
|
|
813
|
+
${PURPLE}${BOLD} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
|
|
814
|
+
${DIM} Auroq OS v${PKG_VERSION} — Sistema Operacional de IA para Experts${RESET}
|
|
815
|
+
`);
|
|
816
|
+
}
|
|
817
|
+
|
|
535
818
|
// ─── CLI ─────────────────────────────────────────────────
|
|
536
819
|
const command = process.argv[2];
|
|
537
820
|
|
|
@@ -540,6 +823,19 @@ if (command === 'init' || command === 'install') {
|
|
|
540
823
|
error(`Falha na instalacao: ${err.message}`);
|
|
541
824
|
process.exit(1);
|
|
542
825
|
});
|
|
826
|
+
} else if (command === 'clone') {
|
|
827
|
+
clone(process.argv[3]).catch(err => {
|
|
828
|
+
error(`Falha ao clonar: ${err.message}`);
|
|
829
|
+
process.exit(1);
|
|
830
|
+
});
|
|
831
|
+
} else if (command === 'fix-gitignore') {
|
|
832
|
+
(async () => {
|
|
833
|
+
step('Protegendo segredos...');
|
|
834
|
+
await applySecretProtections(process.cwd());
|
|
835
|
+
})().catch(err => {
|
|
836
|
+
error(`Falha: ${err.message}`);
|
|
837
|
+
process.exit(1);
|
|
838
|
+
});
|
|
543
839
|
} else if (command === 'login') {
|
|
544
840
|
auth.interactiveLogin().catch(err => {
|
|
545
841
|
error(`Falha no login: ${err.message}`);
|
|
@@ -594,7 +890,9 @@ if (command === 'init' || command === 'install') {
|
|
|
594
890
|
} else {
|
|
595
891
|
showBanner();
|
|
596
892
|
log(`${BOLD}Comandos disponiveis:${RESET}`);
|
|
597
|
-
log(` ${CYAN}init${RESET} Instalar Auroq OS no diretorio atual`);
|
|
893
|
+
log(` ${CYAN}init${RESET} Instalar Auroq OS no diretorio atual (primeira maquina)`);
|
|
894
|
+
log(` ${CYAN}clone${RESET} Continuar o seu negocio NESTA maquina (segunda maquina / colaborador)`);
|
|
895
|
+
log(` ${CYAN}fix-gitignore${RESET} Garantir protecoes de segredo no .gitignore (vault, .env)`);
|
|
598
896
|
log(` ${CYAN}login${RESET} Autenticar com email + senha da Mentoria Arcane`);
|
|
599
897
|
log(` ${CYAN}logout${RESET} Encerrar sessao local`);
|
|
600
898
|
log(` ${CYAN}whoami${RESET} Mostrar usuario autenticado`);
|