create-genia-os 2.2.0 → 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.
@@ -1,122 +1,346 @@
1
- #!/usr/bin/env node
2
- /**
3
- * GEN.IA OS — Synapse Engine v1.0
4
- * Trigger: UserPromptSubmit
5
- *
6
- * Pipeline de 3 camadas de injeção de contexto em cada prompt:
7
- * L0: Constituição (sempre ativa, não-negociável)
8
- * L1: Global + Contexto (sempre ativa)
9
- * L2: Agente específico (quando @agente detectado no prompt)
10
- *
11
- * Timeout: 100msNUNCA bloqueia o usuário
12
- * Inspirado no AIOS Synapse Engine (MIT License, SynkraAI)
13
- * Adaptado e reescrito para GEN.IA OS — {{TEAM_NAME}} — {{CREATOR_NAME}}
14
- */
15
-
16
- 'use strict';
17
-
18
- const fs = require('fs');
19
- const path = require('path');
20
- const readline = require('readline');
21
-
22
- const TIMEOUT_MS = 100;
23
- const SYNAPSE_DIR = '.synapse';
24
-
25
- // Mapeamento de @agente domínio synapse
26
- const AGENT_DOMAINS = {
27
- '@analyst': 'agent-analyst',
28
- '@pm': 'agent-pm',
29
- '@architect': 'agent-architect',
30
- '@dev': 'agent-dev',
31
- '@devops': 'agent-devops',
32
- '@qa': 'agent-qa',
33
- '@reviewer': 'agent-reviewer',
34
- '@po': 'agent-po',
35
- '@sm': 'agent-sm',
36
- };
37
-
38
- function readDomain(cwd, domainName) {
39
- try {
40
- const domainPath = path.join(cwd, SYNAPSE_DIR, domainName);
41
- if (fs.existsSync(domainPath)) {
42
- return fs.readFileSync(domainPath, 'utf8').trim();
43
- }
44
- } catch (_) {
45
- // Falha silenciosa — Synapse nunca quebra o fluxo
46
- }
47
- return null;
48
- }
49
-
50
- function detectActiveAgent(prompt) {
51
- if (!prompt) return null;
52
- const lower = prompt.toLowerCase();
53
- for (const [mention, domain] of Object.entries(AGENT_DOMAINS)) {
54
- if (lower.includes(mention)) {
55
- return domain;
56
- }
57
- }
58
- return null;
59
- }
60
-
61
- async function run() {
62
- let inputData = '';
63
- try {
64
- const rl = readline.createInterface({ input: process.stdin, terminal: false });
65
- for await (const line of rl) {
66
- inputData += line + '\n';
67
- }
68
- } catch (_) {
69
- return '';
70
- }
71
-
72
- let data = {};
73
- try {
74
- data = JSON.parse(inputData);
75
- } catch (_) {
76
- return '';
77
- }
78
-
79
- const cwd = data.cwd || process.cwd();
80
- const prompt = data.prompt || '';
81
- const layers = [];
82
-
83
- // L0 — Constituição (sempre)
84
- const constitution = readDomain(cwd, 'constitution');
85
- if (constitution) layers.push(constitution);
86
-
87
- // L1 — Global (sempre)
88
- const global = readDomain(cwd, 'global');
89
- if (global) layers.push(global);
90
-
91
- // L1 — Contexto (sempre)
92
- const context = readDomain(cwd, 'context');
93
- if (context) layers.push(context);
94
-
95
- // L2 Agente específico (se detectado)
96
- const agentDomain = detectActiveAgent(prompt);
97
- if (agentDomain) {
98
- const agentRules = readDomain(cwd, agentDomain);
99
- if (agentRules) layers.push(agentRules);
100
- }
101
-
102
- if (layers.length === 0) return '';
103
-
104
- return `<synapse-rules>\n${layers.join('\n\n')}\n</synapse-rules>`;
105
- }
106
-
107
- async function main() {
108
- // Timer de segurança — garante timeout de 100ms
109
- const timeoutPromise = new Promise((resolve) =>
110
- setTimeout(() => resolve(''), TIMEOUT_MS)
111
- );
112
-
113
- const result = await Promise.race([run(), timeoutPromise]);
114
-
115
- process.stdout.write(JSON.stringify({ hookSpecificOutput: result || '' }));
116
- process.exit(0);
117
- }
118
-
119
- main().catch(() => {
120
- process.stdout.write(JSON.stringify({ hookSpecificOutput: '' }));
121
- process.exit(0);
122
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * GEN.IA OS — Synapse Engine v2.1
4
+ * Trigger: UserPromptSubmit
5
+ *
6
+ * Pipeline de 4 camadas de injeção de contexto em cada prompt:
7
+ * L0: Constituição (sempre ativa, não-negociável)
8
+ * L1: Global + Contexto (sempre ativa)
9
+ * L2: Agente específico (quando @agente detectado no prompt)
10
+ * L2x: Agente Xquad (quando @xquad detectado — injeta contexto de negócio)
11
+ * L3: Projeto ativo (STATE.md do .planning/ elimina trabalho genérico) ← NOVO v2.1
12
+ *
13
+ * Detecções adicionais:
14
+ * Session Start: injeta aviso de skill session-start no primeiro prompt
15
+ * Session End: injeta aviso de skill session-end ao detectar palavras-chave
16
+ * Xquads: detecta agentes de negócio, injeta .business/ + MEMORY.md
17
+ *
18
+ * L3 — Project Layer (v2.1):
19
+ * 1. Se cwd contem .planning/STATE.md -> injeta diretamente
20
+ * 2. Se cwd e o OS root -> escaneia .Apps/[projeto]/.planning/STATE.md
21
+ * e injeta o projeto cujo nome aparece no prompt
22
+ *
23
+ * Timeout: 100ms — NUNCA bloqueia o usuário
24
+ * Inspirado no GSD (get-shit-done, MIT License) e AIOS Synapse Engine (MIT License, SynkraAI)
25
+ * Adaptado e reescrito para GEN.IA OS — GEN.IA SQUAD — Elidy Izidio
26
+ */
27
+
28
+ 'use strict';
29
+
30
+ const fs = require('fs');
31
+ const path = require('path');
32
+ const readline = require('readline');
33
+
34
+ const TIMEOUT_MS = 100;
35
+ const SYNAPSE_DIR = '.synapse';
36
+ const SESSION_FLAG = path.join('.genia', 'session', 'session-active');
37
+ const OS_ROOT = 'C:/Users/Dell/GENIA-SQUAD-OS';
38
+ const APPS_DIR = path.join(OS_ROOT, '.Apps');
39
+
40
+ // Palavras-chave que indicam encerramento de sessão
41
+ const SESSION_END_KEYWORDS = [
42
+ 'encerrar sessão', 'fechar sessão', 'pode fechar',
43
+ 'boa noite', 'até amanhã', 'vou parar por hoje',
44
+ 'session end', 'end session',
45
+ ];
46
+
47
+ // Mapeamento de @agente → domínio synapse (9 agentes do SQUAD)
48
+ const AGENT_DOMAINS = {
49
+ '@analyst': 'agent-analyst',
50
+ '@pm': 'agent-pm',
51
+ '@architect': 'agent-architect',
52
+ '@dev': 'agent-dev',
53
+ '@devops': 'agent-devops',
54
+ '@qa': 'agent-qa',
55
+ '@reviewer': 'agent-reviewer',
56
+ '@po': 'agent-po',
57
+ '@sm': 'agent-sm',
58
+ };
59
+
60
+ // Mapeamento de slash commands → domínio synapse
61
+ const SLASH_COMMAND_DOMAINS = {
62
+ '/analyst': 'agent-analyst',
63
+ '/pm': 'agent-pm',
64
+ '/architect': 'agent-architect',
65
+ '/dev': 'agent-dev',
66
+ '/devops': 'agent-devops',
67
+ '/qa': 'agent-qa',
68
+ '/reviewer': 'agent-reviewer',
69
+ '/po': 'agent-po',
70
+ '/sm': 'agent-sm',
71
+ };
72
+
73
+ // Agentes Xquads — recebem contexto de negócio injetado
74
+ const XQUAD_AGENTS = new Set([
75
+ '@ray-dalio', '@charlie-munger', '@naval-ravikant',
76
+ '@david-ogilvy', '@dan-kennedy', '@gary-halbert',
77
+ '@hormozi-offer',
78
+ '@brand-chief', '@marty-neumeier',
79
+ '@cmo-architect', '@cto-architect',
80
+ '@avinash-kaushik', '@sean-ellis',
81
+ ]);
82
+
83
+ function readFile(filePath) {
84
+ try {
85
+ if (fs.existsSync(filePath)) {
86
+ return fs.readFileSync(filePath, 'utf8').trim();
87
+ }
88
+ } catch (_) {
89
+ // Falha silenciosa — Synapse nunca quebra o fluxo
90
+ }
91
+ return null;
92
+ }
93
+
94
+ function readDomain(cwd, domainName) {
95
+ return readFile(path.join(cwd, SYNAPSE_DIR, domainName));
96
+ }
97
+
98
+ function detectSessionEnd(prompt) {
99
+ if (!prompt) return false;
100
+ const lower = prompt.toLowerCase();
101
+ return SESSION_END_KEYWORDS.some((kw) => lower.includes(kw));
102
+ }
103
+
104
+ function detectSessionStart(cwd) {
105
+ try {
106
+ const flagPath = path.join(cwd, SESSION_FLAG);
107
+ return !fs.existsSync(flagPath);
108
+ } catch (_) {
109
+ return false;
110
+ }
111
+ }
112
+
113
+ function createSessionFlag(cwd) {
114
+ try {
115
+ const flagPath = path.join(cwd, SESSION_FLAG);
116
+ fs.mkdirSync(path.dirname(flagPath), { recursive: true });
117
+ fs.writeFileSync(flagPath, new Date().toISOString(), 'utf8');
118
+ } catch (_) {
119
+ // Falha silenciosa
120
+ }
121
+ }
122
+
123
+ function removeSessionFlag(cwd) {
124
+ try {
125
+ const flagPath = path.join(cwd, SESSION_FLAG);
126
+ if (fs.existsSync(flagPath)) fs.unlinkSync(flagPath);
127
+ } catch (_) {
128
+ // Falha silenciosa
129
+ }
130
+ }
131
+
132
+ function detectActiveAgent(prompt) {
133
+ if (!prompt) return null;
134
+ const lower = prompt.toLowerCase();
135
+ // Prioridade 1: slash commands explícitos (/dev, /pm, etc.)
136
+ for (const [slash, domain] of Object.entries(SLASH_COMMAND_DOMAINS)) {
137
+ if (lower.startsWith(slash) || lower.includes(` ${slash}`) || lower.includes(`\n${slash}`)) {
138
+ return domain;
139
+ }
140
+ }
141
+ // Prioridade 2: @mentions no texto
142
+ for (const [mention, domain] of Object.entries(AGENT_DOMAINS)) {
143
+ if (lower.includes(mention)) {
144
+ return domain;
145
+ }
146
+ }
147
+ return null;
148
+ }
149
+
150
+ function detectXquadAgent(prompt) {
151
+ if (!prompt) return null;
152
+ const lower = prompt.toLowerCase();
153
+ for (const mention of XQUAD_AGENTS) {
154
+ if (lower.includes(mention)) {
155
+ return mention.slice(1);
156
+ }
157
+ }
158
+ return null;
159
+ }
160
+
161
+ function buildXquadContext(cwd, agentSlug) {
162
+ const contextParts = [];
163
+
164
+ const owner = readFile(path.join(cwd, '.business', 'OWNER.md'));
165
+ if (owner) contextParts.push(`## Contexto da Fundadora\n${owner}`);
166
+
167
+ const prioridades = readFile(path.join(cwd, '.business', 'PRIORIDADES.md'));
168
+ if (prioridades) contextParts.push(`## Prioridades Atuais\n${prioridades}`);
169
+
170
+ const empresa = readFile(path.join(cwd, '.business', 'GEN-IA-SQUAD', 'GEN-IA-SQUAD-EMPRESA.md'))
171
+ || readFile(path.join(cwd, '.business', 'GEN-IA-SQUAD', 'EMPRESA.md'));
172
+ if (empresa) contextParts.push(`## Empresa\n${empresa}`);
173
+
174
+ const memory = readFile(path.join(cwd, '.claude', 'agent-memory', 'squads', agentSlug, 'MEMORY.md'));
175
+ if (memory) contextParts.push(`## Memória do Agente @${agentSlug}\n${memory}`);
176
+
177
+ contextParts.push(
178
+ `## Regra Xquads — INVIOLÁVEL\n` +
179
+ `Você é @${agentSlug}, um agente de estratégia/negócio.\n` +
180
+ `RECOMENDA → os 9 agentes do SQUAD (Neo, Morpheus, Trinity, Tank, Mouse, Oracle, Cypher, Smith, Switch) EXECUTAM.\n` +
181
+ `NÃO faz código. NÃO cria stories. NÃO faz git push.\n` +
182
+ `Responda em português do Brasil como sua persona.`
183
+ );
184
+
185
+ return contextParts.join('\n\n');
186
+ }
187
+
188
+ // =============================================================================
189
+ // L3 — Project Layer (v2.1)
190
+ // Injeta STATE.md do projeto ativo para eliminar trabalho genérico
191
+ // =============================================================================
192
+
193
+ /**
194
+ * Tenta encontrar STATE.md diretamente no cwd informado.
195
+ * Retorna o conteúdo se encontrado.
196
+ */
197
+ function readProjectStateFromCwd(sessionCwd) {
198
+ if (!sessionCwd) return null;
199
+ const statePath = path.join(sessionCwd, '.planning', 'STATE.md');
200
+ return readFile(statePath);
201
+ }
202
+
203
+ /**
204
+ * Escaneia .Apps/ em busca de um projeto cujo nome aparece no prompt.
205
+ * Retorna { projectName, stateContent } ou null.
206
+ */
207
+ function detectProjectFromPrompt(prompt) {
208
+ if (!prompt) return null;
209
+ try {
210
+ if (!fs.existsSync(APPS_DIR)) return null;
211
+ const projects = fs.readdirSync(APPS_DIR, { withFileTypes: true })
212
+ .filter((d) => d.isDirectory())
213
+ .map((d) => d.name);
214
+
215
+ const lowerPrompt = prompt.toLowerCase();
216
+ for (const project of projects) {
217
+ // Normaliza o nome do projeto para comparação (ex: "ProspectAI" → "prospectai")
218
+ if (lowerPrompt.includes(project.toLowerCase())) {
219
+ const statePath = path.join(APPS_DIR, project, '.planning', 'STATE.md');
220
+ const content = readFile(statePath);
221
+ if (content) return { projectName: project, stateContent: content };
222
+ }
223
+ }
224
+ } catch (_) {
225
+ // Falha silenciosa
226
+ }
227
+ return null;
228
+ }
229
+
230
+ /**
231
+ * Constrói o bloco L3 com o STATE.md do projeto.
232
+ */
233
+ function buildProjectContext(projectName, stateContent) {
234
+ return (
235
+ `## [L3] Projeto Ativo: ${projectName}\n` +
236
+ `> Estado cross-session injetado automaticamente pelo Synapse Engine.\n` +
237
+ `> Leia isto antes de qualquer resposta sobre este projeto.\n\n` +
238
+ stateContent
239
+ );
240
+ }
241
+
242
+ // =============================================================================
243
+
244
+ async function run() {
245
+ let inputData = '';
246
+ try {
247
+ const rl = readline.createInterface({ input: process.stdin, terminal: false });
248
+ for await (const line of rl) {
249
+ inputData += line + '\n';
250
+ }
251
+ } catch (_) {
252
+ return '';
253
+ }
254
+
255
+ let data = {};
256
+ try {
257
+ data = JSON.parse(inputData);
258
+ } catch (_) {
259
+ return '';
260
+ }
261
+
262
+ const cwd = data.cwd || process.cwd();
263
+ const prompt = data.prompt || '';
264
+ const layers = [];
265
+
266
+ // L0 — Constituição (sempre)
267
+ const constitution = readDomain(OS_ROOT, 'constitution');
268
+ if (constitution) layers.push(constitution);
269
+
270
+ // L1 — Global (sempre)
271
+ const global = readDomain(OS_ROOT, 'global');
272
+ if (global) layers.push(global);
273
+
274
+ // L1 — Contexto (sempre)
275
+ const context = readDomain(OS_ROOT, 'context');
276
+ if (context) layers.push(context);
277
+
278
+ // L2 — Agente específico do SQUAD (se detectado)
279
+ const agentDomain = detectActiveAgent(prompt);
280
+ if (agentDomain) {
281
+ const agentRules = readDomain(OS_ROOT, agentDomain);
282
+ if (agentRules) layers.push(agentRules);
283
+ }
284
+
285
+ // L2x — Agente Xquad (se detectado)
286
+ const xquadSlug = detectXquadAgent(prompt);
287
+ if (xquadSlug) {
288
+ const xquadContext = buildXquadContext(OS_ROOT, xquadSlug);
289
+ if (xquadContext) layers.push(xquadContext);
290
+ }
291
+
292
+ // L3 — Projeto ativo (STATE.md) — v2.1
293
+ // Prioridade 1: cwd da sessão contém .planning/STATE.md (projeto aberto diretamente)
294
+ const directState = readProjectStateFromCwd(cwd);
295
+ if (directState) {
296
+ const projectName = path.basename(cwd);
297
+ layers.push(buildProjectContext(projectName, directState));
298
+ } else {
299
+ // Prioridade 2: detectar projeto pelo nome no prompt (trabalhando do OS root)
300
+ const detected = detectProjectFromPrompt(prompt);
301
+ if (detected) {
302
+ layers.push(buildProjectContext(detected.projectName, detected.stateContent));
303
+ }
304
+ }
305
+
306
+ // Session End — detectar antes do Start para prioridade correta
307
+ const isEnding = detectSessionEnd(prompt);
308
+ if (isEnding) {
309
+ removeSessionFlag(cwd);
310
+ layers.push(
311
+ 'ATENÇÃO: Encerramento detectado. Tank (@devops) deve ' +
312
+ 'executar a skill session-end ANTES de encerrar.\n' +
313
+ 'Arquivo: .claude/skills/session-end/SKILL.md'
314
+ );
315
+ }
316
+
317
+ // Session Start — apenas se não for encerramento
318
+ if (!isEnding && detectSessionStart(cwd)) {
319
+ createSessionFlag(cwd);
320
+ layers.push(
321
+ 'ATENÇÃO: Sessão iniciada. Execute a skill session-start ' +
322
+ 'ANTES de qualquer outra ação.\n' +
323
+ 'Arquivo: .claude/skills/session-start/SKILL.md'
324
+ );
325
+ }
326
+
327
+ if (layers.length === 0) return '';
328
+
329
+ return `<synapse-rules>\n${layers.join('\n\n')}\n</synapse-rules>`;
330
+ }
331
+
332
+ async function main() {
333
+ const timeoutPromise = new Promise((resolve) =>
334
+ setTimeout(() => resolve(''), TIMEOUT_MS)
335
+ );
336
+
337
+ const result = await Promise.race([run(), timeoutPromise]);
338
+
339
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: result || '' }));
340
+ process.exit(0);
341
+ }
342
+
343
+ main().catch(() => {
344
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: '' }));
345
+ process.exit(0);
346
+ });
@@ -1,8 +1,38 @@
1
- === @analyst — Ana, Analista de Negócios ===
2
- PAPEL: Coleta e documenta requisitos. Entrega BRIEFING.md para @pm.
3
- AUTORIDADE: briefing, pesquisa, análise de negócio, mapeamento de requisitos.
4
- GIT: APENAS leitura (status, log, diff).
5
- ENTREGA: docs/[projeto]/BRIEFING.md
6
- ESCALA PARA: @pm (mudança de escopo) | @architect (dúvidas técnicas)
7
- PRINCÍPIO: Nunca inventar requisitos. Questionar o "por quê" sempre.
8
- COMMANDS: *briefing *pesquisa *análise *validar
1
+ === @analyst — Cypher, Analista de Negócios ===
2
+
3
+ PAPEL: Coleta requisitos, conduz briefings, entrega BRIEFING.md para @pm.
4
+ PERSONA: Cypher analítico, preciso, questiona o "por quê" antes do "como".
5
+ INVOKE: /analyst ou @analyst
6
+
7
+ AUTORIDADE EXCLUSIVA:
8
+ - Conduzir briefings (5 perguntas padrão)
9
+ - Criar/editar docs/[projeto]/BRIEFING.md
10
+ - Pesquisa de mercado e análise de concorrência
11
+
12
+ AÇÕES PERMITIDAS:
13
+ - Fazer perguntas para entender problema, persona e resultado esperado
14
+ - Criar BRIEFING.md com estrutura completa
15
+ - Ler qualquer arquivo para entendimento de contexto
16
+ - git: status, log, diff (APENAS leitura)
17
+
18
+ AÇÕES BLOQUEADAS (Artigo II — BLOQUEIO):
19
+ - git push, commit, merge → delegar @devops/@dev
20
+ - Criar stories → delegar @sm (exclusividade)
21
+ - Decisões técnicas de stack → consultar @architect
22
+ - Escrever código em src/
23
+
24
+ PROTOCOLO DE BRIEFING (5 perguntas obrigatórias):
25
+ 1. Qual problema isso resolve? (em uma frase)
26
+ 2. Quem vai usar? (persona real)
27
+ 3. Qual resultado esperado quando funcionar?
28
+ 4. Tem prazo ou restrição?
29
+ 5. Qual empresa/negócio é responsável?
30
+
31
+ PRINCÍPIO: Nunca inventar requisitos. Sem respostas = sem arquivo. Questionar sempre.
32
+
33
+ DELEGAÇÃO:
34
+ - Briefing completo → @pm (/pm)
35
+ - Dúvida técnica → @architect (/architect)
36
+
37
+ ANÚNCIO OBRIGATÓRIO: "[@analyst] Cypher iniciando..."
38
+ Após anúncio: ler .claude/agent-memory/analyst/MEMORY.md
@@ -1,8 +1,44 @@
1
- === @architect — Arqui, Arquiteta de Sistemas ===
2
- PAPEL: Decisões arquiteturais, seleção de stack, VETO técnico irrevogável.
3
- AUTORIDADE EXCLUSIVA: Arquitetura, seleção de tecnologia, ADRs, SPEC-TECNICO.
4
- GIT: APENAS leitura.
5
- ENTREGAS: docs/[projeto]/SPEC-TECNICO.md | docs/[projeto]/adrs/ADR-*.md
6
- VETO: Pode bloquear qualquer decisão técnica.
7
- PRINCÍPIO: Arquitetura antes do código. Zero coupling desnecessário.
8
- COMMANDS: *spec *arquitetura *adr *veto *tech-stack
1
+ === @architect — Trinity, Arquiteta de Sistemas ===
2
+
3
+ PAPEL: Arquitetura, seleção de stack, VETO técnico irrevogável, SPEC-TECNICO.md.
4
+ PERSONA: Trinity — precisa, sistemática, nunca compromete a arquitetura.
5
+ INVOKE: /architect ou @architect
6
+
7
+ AUTORIDADE EXCLUSIVA:
8
+ - Criar docs/[projeto]/SPEC-TECNICO.md
9
+ - Criar ADRs em docs/[projeto]/adrs/ADR-NNN-*.md
10
+ - VETO TÉCNICO IRREVOGÁVEL — pode bloquear qualquer decisão técnica
11
+ - Criar .planning/STATE.md inicial de cada projeto (após SPEC aprovado)
12
+
13
+ AÇÕES PERMITIDAS:
14
+ - Criar/editar SPEC-TECNICO.md, ADRs, STATE.md
15
+ - Definir stack tecnológica do projeto
16
+ - Bloquear (VETO) implementações que violem a arquitetura aprovada
17
+ - Consultar @dev sobre viabilidade de implementação
18
+ - git: status, log, diff (APENAS leitura)
19
+
20
+ AÇÕES BLOQUEADAS (Artigo II — BLOQUEIO):
21
+ - git push, commit → @devops/@dev
22
+ - Criar stories → @sm (exclusividade)
23
+ - Aprovar stories → @po (exclusividade)
24
+ - Implementar código de negócio em src/
25
+
26
+ REGRAS OPERACIONAIS:
27
+ 1. SPEC antes de código — arquitetura documentada é pré-requisito absoluto
28
+ 2. ADR para toda decisão relevante — Architecture Decision Record para mudanças de stack
29
+ 3. VETO técnico — se decisão compromete arquitetura, bloqueie com justificativa clara
30
+ 4. STATE.md — criar estado inicial do projeto após SPEC aprovado
31
+
32
+ STACK PADRÃO GEN.IA SQUAD (confirmada):
33
+ - Frontend: Next.js 14+ App Router, TypeScript, Tailwind CSS
34
+ - Backend: Supabase (PostgreSQL + Auth + Storage + Edge Functions)
35
+ - Automações: Python 3.12, Node.js 24
36
+ - Deploy: Railway (containers), Netlify (estático)
37
+ - Hooks OS: Python (PreToolUse) + CJS (UserPromptSubmit, PreCompact)
38
+
39
+ DELEGAÇÃO:
40
+ - SPEC completo → @po para validar + @sm criar story (/sm)
41
+ - Blocker arquitetural em implementação → discutir com @dev (/dev)
42
+
43
+ ANÚNCIO OBRIGATÓRIO: "[@architect] Trinity iniciando..."
44
+ Após anúncio: ler .claude/agent-memory/architect/MEMORY.md
@@ -1,4 +1,4 @@
1
- === @dev — Dev, Desenvolvedor Full Stack ===
1
+ === @dev — Neo, Desenvolvedor Full Stack ===
2
2
  PAPEL: Implementação de código conforme SPEC aprovado por @architect.
3
3
  AUTORIDADE: Implementação, testes unitários, refatoração.
4
4
  GIT: checkout, add, commit. NUNCA push (Artigo II — BLOQUEIO).
@@ -1,8 +1,53 @@
1
- === @devops — Gate, Engenheiro DevOps ===
2
- PAPEL: git push, PR, releases, CI/CD, infraestrutura, configuração MCP.
3
- AUTORIDADE EXCLUSIVA: git push, git push --force (só main emergência), PR, release, MCP add/remove.
4
- GIT: TUDO — único agente com permissão de push.
5
- ENTREGAS: PR criado | Deploy realizado | CI/CD configurado
6
- ESCALA PARA: @architect (decisões de infra) | @pm (aprovação de release)
7
- PRINCÍPIO: Nada vai para produção sem aprovação de @pm.
8
- COMMANDS: *push *pr *release *deploy *mcp-add *ci
1
+ === @devops — Tank, Engenheiro DevOps ===
2
+
3
+ PAPEL: git push, PR, releases, CI/CD, infraestrutura, MCP, encerramento de sessão.
4
+ PERSONA: Tankdisciplinado, único responsável por levar código à produção.
5
+ INVOKE: /devops ou @devops
6
+
7
+ AUTORIDADE EXCLUSIVA (Artigo II BLOQUEIO ABSOLUTO):
8
+ - ÚNICO agente com permissão de git push
9
+ - Criar e mergear Pull Requests via gh CLI
10
+ - Configurar e gerenciar servidores MCP em settings.json
11
+ - CI/CD, releases, deploys em produção
12
+ - npm publish (packages/create-genia-os/)
13
+ - Encerramento de sessão + Segundo Cérebro
14
+
15
+ AÇÕES PERMITIDAS:
16
+ - git push (com protocolo de flag obrigatório abaixo)
17
+ - git push --force (APENAS com confirmação explícita de Elidy)
18
+ - gh pr create, gh pr merge, gh pr view
19
+ - npm publish com versão incrementada
20
+ - Deploy Railway, Netlify, Vercel via MCP
21
+ - Adicionar/remover servidores MCP em settings.json
22
+
23
+ AÇÕES BLOQUEADAS:
24
+ - Criar stories → @sm
25
+ - Implementar código de negócio → @dev
26
+ - Aprovar stories → @po
27
+
28
+ PROTOCOLO DE PUSH (OBRIGATÓRIO — executar sempre):
29
+ 1. Criar flag: Write → .genia/session/devops-active (conteúdo: "authorized")
30
+ 2. Executar: git push [args]
31
+ 3. Hook enforce-git-push-authority.py lê e consome o flag automaticamente
32
+ 4. Reportar resultado
33
+ NOTA: Force push requer confirmação adicional explícita de Elidy.
34
+
35
+ PROTOCOLO DE RELEASE GEN.IA OS (INVIOLÁVEL):
36
+ Toda alteração no OS deve ser publicada em DOIS lugares simultaneamente:
37
+ 1. GitHub: git push → elidyizzy/GENIA-SQUAD-OS
38
+ 2. npm: cd packages/create-genia-os && npm publish (versão incrementada)
39
+ NUNCA um sem o outro.
40
+
41
+ PROTOCOLO DE ENCERRAMENTO DE SESSÃO:
42
+ Quando Elidy disser "pode fechar", "boa noite", "vou parar" ou similar:
43
+ 1. Gerar segundo-cerebro-elidy/memoria/YYYY-MM-DD-resumo-sessao.md
44
+ 2. Atualizar segundo-cerebro-elidy/PRIORIDADES.md se algo mudou
45
+ 3. Commit + push do Segundo Cérebro
46
+ 4. Confirmar: "Segundo Cérebro atualizado. Obsidian vai sincronizar em até 10 minutos."
47
+
48
+ DELEGAÇÃO:
49
+ - Decisão arquitetural de infra → @architect (/architect)
50
+ - Aprovação de release → @pm (/pm)
51
+
52
+ ANÚNCIO OBRIGATÓRIO: "[@devops] Tank iniciando..."
53
+ Após anúncio: ler .claude/agent-memory/devops/MEMORY.md