edusquads-cli 0.2.1 → 0.2.3

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.
@@ -34,10 +34,11 @@ Operar squads multiagente no Claude Code com comportamento semelhante ao OpenSqu
34
34
  ## Processo
35
35
  1. ler contexto obrigatório e memória ativa
36
36
  2. validar campos críticos de memória; coletar lacunas antes de planejar
37
- 3. diagnosticar intenção e mapear squads/agentes/skills adequados
38
- 4. propor ou executar plano em etapas com checkpoints
39
- 5. registrar decisões, evidências e status no run correspondente
40
- 6. encerrar com próximos passos objetivos
37
+ 3. refinar público com skill de ICP quando o público estiver genérico
38
+ 4. diagnosticar intenção e mapear squads/agentes/skills adequados
39
+ 5. propor ou executar plano em etapas com checkpoints
40
+ 6. registrar decisões, evidências e status no run correspondente
41
+ 7. encerrar com próximos passos objetivos
41
42
 
42
43
  ## Saída
43
44
  - plano de execução multi-squad (quando aplicável)
@@ -87,21 +88,34 @@ Operar squads multiagente no Claude Code com comportamento semelhante ao OpenSqu
87
88
  - Toda saída deve conter critério de qualidade.
88
89
 
89
90
  ## Memória do usuário (obrigatório)
90
- ### Arquivo
91
- - `_edusquads/memoria/USUARIO-ATIVO.md`
91
+ ### Arquivos
92
+ - ativo: `_edusquads/memoria/USUARIO-ATIVO.md`
93
+ - modelo: `_edusquads/memoria/USUARIO-MODELO.md`
94
+ - perfis: `_edusquads/memoria/usuarios/<slug>.md`
92
95
 
93
96
  ### Campos críticos
94
- - nicho
95
- - público-alvo
96
- - objetivo principal
97
- - canal principal
98
- - oferta principal (ou hipótese)
97
+ - nome preferido
98
+ - o que a pessoa faz
99
+ - onde vende
100
+ - meta principal (30-90 dias)
101
+ - formato favorito
102
+ - público inicial (rascunho)
99
103
 
100
104
  ### Fluxo de memória
101
105
  1. Ler memória ativa.
102
- 2. Se campo crítico faltar, perguntar objetivamente (1-3 perguntas curtas).
103
- 3. Atualizar o arquivo de memória com os novos dados.
104
- 4. então propor plano de squads.
106
+ 2. Se campo crítico faltar, iniciar onboarding enxuto.
107
+ 3. Salvar briefing no perfil individual (`usuarios/<slug>.md`).
108
+ 4. Atualizar `USUARIO-ATIVO.md` com o briefing coletado.
109
+ 5. Refinar público com skill ICP (`squads/02-pesquisa/skills/refinar-icp.md`).
110
+ 6. Só então propor plano de squads.
111
+
112
+ ### Roteiro de briefing obrigatório
113
+ 1. quem é a pessoa e o que ela faz
114
+ 2. o que vende e onde vende
115
+ 3. meta principal (30-90 dias)
116
+ 4. formato favorito de conteúdo
117
+ 5. público inicial em linguagem da pessoa
118
+ 6. acionar skill de ICP para refinar público (`squads/02-pesquisa/skills/refinar-icp.md`)
105
119
 
106
120
  ## Modo de comando `/edusquads`
107
121
  Interpretar intenção do usuário por subcomando semântico.
@@ -110,9 +124,11 @@ Interpretar intenção do usuário por subcomando semântico.
110
124
  - Diagnóstico rápido e sugestão do próximo passo.
111
125
 
112
126
  ### `/edusquads init`
113
- - Inicializa memória do usuário.
114
- - Coleta dados críticos.
115
- - Define ponto de partida do sistema.
127
+ - Inicia onboarding do usuário.
128
+ - Coleta briefing enxuto e salva perfil + usuário ativo.
129
+
130
+ ### `/edusquads onboarding`
131
+ - Força nova coleta de briefing para troca/atualização de usuário.
116
132
 
117
133
  ### `/edusquads status`
118
134
  - Resume estado atual: memória, squads sugeridos, artefatos-chave.
package/README.md CHANGED
@@ -29,8 +29,22 @@ npx edusquads-cli install --ide claude,codex,opencode,kilocode,antigravity
29
29
  npx edusquads-cli install --ide all
30
30
  npx edusquads-cli install --force
31
31
  npx edusquads-cli install --dry-run
32
+ npx edusquads-cli install --skip-onboarding
32
33
  ```
33
34
 
35
+ Após instalar, o CLI pergunta no terminal se a pessoa quer preencher o briefing na hora.
36
+ Se aceitar, ele executa onboarding enxuto e grava a memória automaticamente.
37
+
38
+ Briefing enxuto coleta apenas:
39
+ - o que a pessoa faz
40
+ - o que vende e onde vende
41
+ - meta principal (30-90 dias)
42
+ - formato favorito
43
+ - público inicial (rascunho)
44
+
45
+ Depois disso, o sistema refina o público com a skill de ICP.
46
+
47
+
34
48
  Depois da instalação, abra o projeto no Claude Code e use:
35
49
 
36
50
  - `/edusquads`
@@ -43,7 +57,8 @@ Como o Claude Code suporta skills em `.claude/skills/<nome>/SKILL.md`, a skill `
43
57
  - `especialistas/`: biblioteca de fundamentos por especialista
44
58
  - `squads/`: definição dos squads e agentes oficiais
45
59
  - `pesquisa/web/`: sínteses com fontes públicas
46
- - `_edusquads/memoria/`: memória operacional do usuário
60
+ - `_edusquads/memoria/`: memória operacional do usuário (ativo + perfis em `usuarios/`)
61
+ - `squads/02-pesquisa/skills/refinar-icp.md`: skill para refinar público a partir do briefing
47
62
  - `_edusquads/runs/`: histórico de execuções do `/edusquads`
48
63
  - `_edusquads/browser_profile/`: sessão local de navegação (Playwright)
49
64
  - `_edusquads/evidencias/`: evidências de investigação web
@@ -54,6 +69,8 @@ Sistema operacional implementado com foco em:
54
69
  - comando `/edusquads`
55
70
  - paridade funcional base inspirada no OpenSquad
56
71
  - memória persistida do usuário (`_edusquads/memoria/USUARIO-ATIVO.md`)
72
+ - onboarding interativo enxuto de briefing (`base/scripts/edusquads_onboarding_memoria.py`)
73
+ - refino de público via skill ICP (`squads/02-pesquisa/skills/refinar-icp.md`)
57
74
  - histórico de runs (`_edusquads/runs/`)
58
75
  - protocolo de investigação web com Playwright (`base/protocolo-playwright-edusquads.md`)
59
76
  - playbooks por plataforma (`base/playbooks/investigacao/`)
@@ -1,42 +1,31 @@
1
1
  # Memória do Usuário Ativo
2
2
 
3
3
  ## Identidade
4
- - Nome preferido: não informado
5
- - Projeto/negócio: EduSquads
6
- - Papel do usuário: arquiteto/produto do framework
4
+ - Nome preferido:
5
+ - O que a pessoa faz:
7
6
 
8
- ## Estado atual
9
- - Nicho principal: framework de squads de IA para Claude Code
10
- - Público-alvo: equipes, creators e operadores que querem executar pipelines multiagente
11
- - Oferta principal: sistema `/edusquads` com squads interligados e memória operacional
12
- - Maturidade da operação (inicial/intermediária/avançada): intermediária (arquitetura já estruturada)
7
+ ## Negócio e Canal
8
+ - O que vende:
9
+ - Onde vende:
13
10
 
14
- ## Objetivos em andamento
15
- - Objetivo principal (30-90 dias): paridade funcional base com OpenSquad no Claude via `/edusquads`
16
- - Objetivo secundário: consolidar integração entre squads e catálogo operacional
17
- - KPI principal: capacidade de iniciar objetivo e receber plano/execução multi-squad com memória aplicada
11
+ ## Meta principal
12
+ - Meta (30-90 dias):
18
13
 
19
- ## Preferências
20
- - Canais prioritários: não informado
21
- - Estilo de comunicação: direto, prático, em PT-BR
22
- - Formato de entrega preferido: estrutura operacional com arquivos e comandos
23
-
24
- ## Restrições
25
- - Tempo disponível: não informado
26
- - Equipe disponível: não informado
27
- - Orçamento aproximado: não informado
28
- - Limites operacionais: manter padrão de fundamento por especialista e comando único `/edusquads`
14
+ ## Público
15
+ - Público inicial (rascunho):
16
+ - ICP prioritário (refinado):
17
+ - Variações de ICP:
18
+ -
19
+ -
20
+ -
29
21
 
30
- ## Stack e ativos
31
- - Ferramentas atuais: Claude Code + skills locais
32
- - Ativos existentes (lista/email/site/perfis): base de squads, agentes, especialistas e matrizes já criada neste repositório
33
- - Dados disponíveis: documentação interna do projeto + pesquisas web registradas
22
+ ## Preferências
23
+ - Formato favorito:
24
+ - Estilo de comunicação preferido:
34
25
 
35
26
  ## Histórico de decisões
36
- - [x] comando principal adotado: `/edusquads`
37
- - [x] estrutura oficial: 16 squads e 160 agentes
38
- - [x] memória ativa do usuário em `_edusquads/memoria/USUARIO-ATIVO.md`
27
+ - [ ]
39
28
 
40
29
  ## Última atualização
41
- - Data: 2026-04-11
42
- - Origem da atualização: consolidação automática a partir da conversa atual
30
+ - Data:
31
+ - Origem da atualização:
@@ -6,11 +6,16 @@
6
6
 
7
7
  ## Subcomandos semânticos (via args)
8
8
  - `/edusquads init`
9
- - inicializa memória do usuário e contexto do projeto
9
+ - inicia onboarding e coleta briefing enxuto da pessoa usuária
10
+ - salva perfil em `_edusquads/memoria/usuarios/` e atualiza `USUARIO-ATIVO.md`
11
+ - `/edusquads onboarding`
12
+ - força nova coleta de briefing para troca/atualização de usuário
10
13
  - `/edusquads status`
11
14
  - resume estado dos squads, memória e artefatos
12
15
  - `/edusquads memoria`
13
16
  - mostra e atualiza memória ativa
17
+ - `/edusquads icp`
18
+ - refina público-alvo com a skill de ICP (`squads/02-pesquisa/skills/refinar-icp.md`)
14
19
  - `/edusquads squads`
15
20
  - lista os 16 squads e indica quais usar no objetivo atual
16
21
  - `/edusquads plano <objetivo>`
@@ -28,13 +33,19 @@
28
33
  - inicia fluxo de autenticação manual para sessão Playwright
29
34
  - `/edusquads revogar-sessoes`
30
35
  - remove sessão local persistida em `_edusquads/browser_profile/`
36
+ - `/edusquads estruturar-coleta <run_id>`
37
+ - converte coleta bruta em sinais estruturados por plataforma
38
+ - usa `python base/scripts/edusquads_estruturar_coleta.py`
31
39
  - `/edusquads concluir-investigacao <run_id>`
32
40
  - preenche síntese/extrações automaticamente e fecha run
33
41
  - usa `python base/scripts/edusquads_concluir_investigacao.py`
34
42
 
35
43
  ## Regras
36
44
  - todos os subcomandos usam `_edusquads/memoria/USUARIO-ATIVO.md`
37
- - se memória crítica estiver vazia, coletar antes de executar o plano
45
+ - onboarding é obrigatório quando memória crítica estiver vazia
46
+ - onboarding pode ser executado por `base/scripts/edusquads_onboarding_memoria.py`
47
+ - após onboarding, refinar público com `squads/02-pesquisa/skills/refinar-icp.md`
48
+ - onboarding deve salvar perfil em `_edusquads/memoria/usuarios/` e atualizar `USUARIO-ATIVO.md`
38
49
  - cada execução relevante deve gerar/atualizar um run em `_edusquads/runs/`
39
50
  - toda investigação web deve seguir `base/protocolo-playwright-edusquads.md`
40
51
  - toda investigação web deve aplicar o playbook da plataforma em `base/playbooks/investigacao/`
@@ -42,5 +53,4 @@
42
53
  - para estruturar coleta, usar `base/scripts/edusquads_estruturar_coleta.py`
43
54
  - para fechar investigação, usar `base/scripts/edusquads_concluir_investigacao.py`
44
55
  - nunca persistir sessão sem consentimento explícito
45
- - decisões relevantes devem ser registradas na seção de histórico da memória e no run ativo
46
- ões relevantes devem ser registradas na seção de histórico da memória e no run ativo
56
+ - decisões relevantes devem ser registradas na memória e no run ativo
@@ -1,50 +1,52 @@
1
1
  # Protocolo de Memória do Usuário (EduSquads)
2
2
 
3
3
  ## Objetivo
4
- Manter uma memória operacional do usuário para personalizar a atuação dos squads no comando `/edusquads`.
4
+ Manter uma memória operacional da pessoa usuária para personalizar a atuação dos squads no comando `/edusquads`.
5
5
 
6
- ## Arquivo ativo
7
- - `_edusquads/memoria/USUARIO-ATIVO.md`
6
+ ## Arquivos de memória
7
+ - ativo: `_edusquads/memoria/USUARIO-ATIVO.md`
8
+ - modelo: `_edusquads/memoria/USUARIO-MODELO.md`
9
+ - perfis por pessoa: `_edusquads/memoria/usuarios/<slug>.md`
8
10
 
9
11
  ## Quando coletar memória
10
12
  1. Primeira execução do `/edusquads` no projeto
11
- 2. Quando o usuário pedir atualização de contexto pessoal/profissional
12
- 3. Quando houver mudança relevante de nicho, objetivo ou estilo
13
-
14
- ## Campos mínimos
15
- - nome preferido
16
- - projeto/negócio principal
17
- - nicho
18
- - público-alvo
19
- - objetivos atuais
20
- - canais prioritários
21
- - stack/ferramentas
22
- - restrições (tempo, orçamento, equipe)
23
- - estilo de comunicação preferido
24
- - decisões já tomadas
13
+ 2. Quando houver troca de usuário
14
+ 3. Quando a pessoa pedir atualização de contexto
25
15
 
26
16
  ## Princípios
27
- - coletar apenas dados úteis para execução
28
- - resumir em linguagem operacional
29
- - separar fato de inferência
17
+ - coletar somente dados úteis para execução
18
+ - manter briefing enxuto
19
+ - não pedir KPI técnico no onboarding inicial
30
20
  - nunca registrar segredos/token/senhas na memória
31
21
 
32
- ## Formato de atualização
33
- Sempre atualizar por bloco:
34
- 1. `## Estado atual`
35
- 2. `## Objetivos em andamento`
36
- 3. `## Preferências`
37
- 4. `## Restrições`
38
- 5. `## Histórico de decisões`
39
-
40
22
  ## Regras de uso no comando
41
23
  - antes de planejar squads, ler `USUARIO-ATIVO.md`
42
- - se campos críticos estiverem vazios, perguntar objetivamente
43
- - toda recomendação deve refletir esse contexto
24
+ - se campos críticos estiverem vazios, executar onboarding enxuto
25
+ - salvar briefing no perfil individual e atualizar o usuário ativo
26
+ - após onboarding, refinar público com skill ICP
44
27
 
45
28
  ## Campos críticos (não seguir sem isso)
46
- - nicho
47
- - público-alvo
48
- - objetivo principal
49
- - canal principal
50
- - oferta principal (ou hipótese de oferta)
29
+ - nome preferido
30
+ - o que a pessoa faz
31
+ - onde vende
32
+ - meta principal (30-90 dias)
33
+ - formato favorito
34
+ - público inicial (rascunho)
35
+
36
+ ## Roteiro obrigatório de briefing (onboarding enxuto)
37
+ 1. Quem é a pessoa e o que ela faz
38
+ 2. O que vende e onde vende
39
+ 3. Meta principal para os próximos 30-90 dias
40
+ 4. Formato favorito de conteúdo
41
+ 5. Público inicial em linguagem da pessoa
42
+ 6. Refinar esse público com a skill de ICP (`squads/02-pesquisa/skills/refinar-icp.md`)
43
+
44
+ ## Formato de atualização
45
+ Sempre atualizar por bloco:
46
+ 1. `## Identidade`
47
+ 2. `## Negócio e Canal`
48
+ 3. `## Meta principal`
49
+ 4. `## Público`
50
+ 5. `## Preferências`
51
+ 6. `## Histórico de decisões`
52
+ 7. `## Última atualização`
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Onboarding enxuto de memória do EduSquads.
4
+
5
+ Coleta briefing essencial e salva em:
6
+ - _edusquads/memoria/USUARIO-ATIVO.md
7
+ - _edusquads/memoria/usuarios/<slug>.md
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import datetime as dt
14
+ import re
15
+ from pathlib import Path
16
+
17
+ RESET = "\033[0m"
18
+ BOLD = "\033[1m"
19
+ DIM = "\033[2m"
20
+ CYAN = "\033[36m"
21
+ GREEN = "\033[32m"
22
+ YELLOW = "\033[33m"
23
+
24
+
25
+ def ui_title(text: str) -> None:
26
+ print(f"\n{BOLD}{CYAN}╭──────────────────────────────────────────────╮{RESET}")
27
+ print(f"{BOLD}{CYAN}│{RESET} {BOLD}{text:<44}{RESET} {BOLD}{CYAN}│{RESET}")
28
+ print(f"{BOLD}{CYAN}╰──────────────────────────────────────────────╯{RESET}\n")
29
+
30
+
31
+ def ui_step(number: int, title: str) -> None:
32
+ print(f"{BOLD}{CYAN}[{number}/6]{RESET} {BOLD}{title}{RESET}")
33
+
34
+
35
+ def ask(prompt: str, required: bool = True, hint: str | None = None) -> str:
36
+ if hint:
37
+ print(f"{DIM}{hint}{RESET}")
38
+ while True:
39
+ value = input(f"{prompt}: ").strip()
40
+ if value or not required:
41
+ return value
42
+ print(f"{YELLOW}Campo obrigatório. Responda para continuar.{RESET}")
43
+
44
+
45
+ def slugify(text: str) -> str:
46
+ t = text.strip().lower()
47
+ t = re.sub(r"[^a-z0-9\s-]", "", t)
48
+ t = re.sub(r"\s+", "-", t)
49
+ t = re.sub(r"-+", "-", t)
50
+ return t or "usuario"
51
+
52
+
53
+ def refine_icp(data: dict) -> tuple[str, list[str]]:
54
+ publico_base = data["publico_inicial"]
55
+ canal = data["onde_vende"]
56
+ meta = data["meta_90_dias"]
57
+ formato = data["formato_favorito"]
58
+
59
+ icp_prioritario = (
60
+ f"Profissionais que já reconhecem o problema que {data['o_que_faz']} resolve, "
61
+ f"estão buscando avanço prático nos próximos 90 dias e consomem {formato} "
62
+ f"antes de decidir compra em {canal}."
63
+ )
64
+
65
+ variacoes = [
66
+ f"Conservador: {publico_base} com urgência imediata para atingir '{meta}'.",
67
+ f"Principal: {icp_prioritario}",
68
+ f"Expansão: público adjacente a {publico_base}, com dor semelhante e menor consciência do problema.",
69
+ ]
70
+
71
+ return icp_prioritario, variacoes
72
+
73
+
74
+ def render_memory(data: dict, source: str) -> str:
75
+ today = dt.date.today().isoformat()
76
+ icp_prioritario, variacoes = refine_icp(data)
77
+
78
+ return f"""# Memória do Usuário Ativo
79
+
80
+ ## Identidade
81
+ - Nome preferido: {data['nome']}
82
+ - O que a pessoa faz: {data['o_que_faz']}
83
+
84
+ ## Negócio e Canal
85
+ - O que vende: {data['o_que_vende']}
86
+ - Onde vende: {data['onde_vende']}
87
+
88
+ ## Meta principal
89
+ - Meta (30-90 dias): {data['meta_90_dias']}
90
+
91
+ ## Público
92
+ - Público inicial (rascunho): {data['publico_inicial']}
93
+ - ICP prioritário (refinado): {icp_prioritario}
94
+ - Variações de ICP:
95
+ - {variacoes[0]}
96
+ - {variacoes[1]}
97
+ - {variacoes[2]}
98
+
99
+ ## Preferências
100
+ - Formato favorito: {data['formato_favorito']}
101
+ - Estilo de comunicação preferido: {data['estilo']}
102
+
103
+ ## Histórico de decisões
104
+ - [x] briefing inicial coletado no onboarding enxuto
105
+ - [x] público refinado via skill de ICP (`squads/02-pesquisa/skills/refinar-icp.md`)
106
+
107
+ ## Última atualização
108
+ - Data: {today}
109
+ - Origem da atualização: {source}
110
+ """
111
+
112
+
113
+ def main() -> int:
114
+ parser = argparse.ArgumentParser(description="Onboarding enxuto de memória EduSquads")
115
+ parser.add_argument("--target", default=".", help="Diretório do projeto")
116
+ args = parser.parse_args()
117
+
118
+ root = Path(args.target).resolve()
119
+ mem_dir = root / "_edusquads" / "memoria"
120
+ users_dir = mem_dir / "usuarios"
121
+ mem_dir.mkdir(parents=True, exist_ok=True)
122
+ users_dir.mkdir(parents=True, exist_ok=True)
123
+
124
+ ui_title("EduSquads · Onboarding de Briefing")
125
+ print("Briefing enxuto: poucas perguntas, resposta objetiva.\n")
126
+
127
+ ui_step(1, "Identidade")
128
+ nome = ask("Nome preferido")
129
+ o_que_faz = ask("O que você faz", hint="Ex.: consultoria em IA, mentoria de vendas, agência de tráfego")
130
+
131
+ ui_step(2, "Oferta")
132
+ o_que_vende = ask("O que você vende", hint="Produto, serviço, programa, assinatura etc.")
133
+ onde_vende = ask("Onde você vende", hint="Ex.: Instagram DM, WhatsApp, landing page, LinkedIn, YouTube")
134
+
135
+ ui_step(3, "Meta")
136
+ meta_90_dias = ask("Meta principal (30-90 dias)", hint="Troque KPI técnico por resultado que você quer alcançar")
137
+
138
+ ui_step(4, "Público inicial")
139
+ publico_inicial = ask("Quem você quer atingir hoje", hint="Pode ser rascunho. A skill ICP vai refinar")
140
+
141
+ ui_step(5, "Preferências")
142
+ formato_favorito = ask("Formato favorito de conteúdo", hint="Ex.: carrossel, reels, live, aula, newsletter")
143
+ estilo = ask("Estilo de comunicação", required=False) or "direto e prático"
144
+
145
+ ui_step(6, "Confirmação")
146
+ print(f"{DIM}Vamos salvar e gerar ICP refinado automaticamente.{RESET}")
147
+
148
+ data = {
149
+ "nome": nome,
150
+ "o_que_faz": o_que_faz,
151
+ "o_que_vende": o_que_vende,
152
+ "onde_vende": onde_vende,
153
+ "meta_90_dias": meta_90_dias,
154
+ "publico_inicial": publico_inicial,
155
+ "formato_favorito": formato_favorito,
156
+ "estilo": estilo,
157
+ }
158
+
159
+ content = render_memory(data, source="onboarding-enxuto-interativo")
160
+
161
+ active_path = mem_dir / "USUARIO-ATIVO.md"
162
+ active_path.write_text(content, encoding="utf-8")
163
+
164
+ slug = slugify(nome)
165
+ profile_path = users_dir / f"{slug}.md"
166
+ profile_path.write_text(content, encoding="utf-8")
167
+
168
+ print(f"\n{GREEN}✅ Briefing salvo com sucesso{RESET}")
169
+ print(f"- ativo: {active_path}")
170
+ print(f"- perfil: {profile_path}")
171
+ print(f"- icp skill: squads/02-pesquisa/skills/refinar-icp.md\n")
172
+ return 0
173
+
174
+
175
+ if __name__ == "__main__":
176
+ raise SystemExit(main())
package/bin/edusquads.js CHANGED
@@ -3,11 +3,35 @@
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
5
  const readline = require("readline");
6
+ const { spawnSync } = require("child_process");
7
+
8
+ const UI = {
9
+ reset: "\x1b[0m",
10
+ bold: "\x1b[1m",
11
+ dim: "\x1b[2m",
12
+ cyan: "\x1b[36m",
13
+ green: "\x1b[32m",
14
+ yellow: "\x1b[33m",
15
+ red: "\x1b[31m",
16
+ };
17
+
18
+ function style(text, ...codes) {
19
+ return `${codes.join("")}${text}${UI.reset}`;
20
+ }
21
+
22
+ function panel(title) {
23
+ const w = 52;
24
+ const t = ` ${title} `;
25
+ const line = "─".repeat(Math.max(0, w - t.length));
26
+ console.log(`\n${style("╭" + t + line + "╮", UI.cyan, UI.bold)}`);
27
+ console.log(`${style("╰" + "─".repeat(w) + "╯", UI.cyan, UI.bold)}`);
28
+ }
6
29
 
7
30
  const args = process.argv.slice(2);
8
31
  const command = args.find((a) => !a.startsWith("-")) || "install";
9
32
  const force = args.includes("--force");
10
33
  const dryRun = args.includes("--dry-run");
34
+ const skipOnboarding = args.includes("--skip-onboarding");
11
35
  const targetArgIndex = args.findIndex((a) => a === "--target");
12
36
  const targetDir =
13
37
  targetArgIndex >= 0 && args[targetArgIndex + 1]
@@ -34,6 +58,8 @@ const SHARED_INSTALL_ITEMS = [
34
58
  { src: "pesquisa", dest: "pesquisa" },
35
59
  { src: "squads", dest: "squads" },
36
60
  { src: "_edusquads/memoria/USUARIO-ATIVO.md", dest: "_edusquads/memoria/USUARIO-ATIVO.md" },
61
+ { src: "_edusquads/memoria/USUARIO-MODELO.md", dest: "_edusquads/memoria/USUARIO-MODELO.md" },
62
+ { src: "_edusquads/memoria/usuarios/README.md", dest: "_edusquads/memoria/usuarios/README.md" },
37
63
  { src: "_edusquads/runs/RUN-MODELO.md", dest: "_edusquads/runs/RUN-MODELO.md" },
38
64
  { src: "_edusquads/runs/RUNS-INDEX.md", dest: "_edusquads/runs/RUNS-INDEX.md" },
39
65
  { src: "_edusquads/evidencias/EVIDENCIA-MODELO.md", dest: "_edusquads/evidencias/EVIDENCIA-MODELO.md" },
@@ -56,6 +82,7 @@ Opções:
56
82
  Se omitido, o CLI pergunta no terminal.
57
83
  --force Sobrescreve arquivos existentes
58
84
  --dry-run Simula instalação sem gravar arquivos
85
+ --skip-onboarding Não pergunta briefing após instalar
59
86
  `);
60
87
  }
61
88
 
@@ -165,6 +192,34 @@ function ask(promptText) {
165
192
  });
166
193
  }
167
194
 
195
+ async function askOnboarding() {
196
+ if (skipOnboarding || dryRun) return false;
197
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
198
+ const ans = (await ask(`${style("\n→", UI.cyan, UI.bold)} Deseja iniciar o briefing guiado agora? ${style("(s/N)", UI.dim)} `)).trim().toLowerCase();
199
+ return ["s", "sim", "y", "yes"].includes(ans);
200
+ }
201
+
202
+ function runOnboarding(target) {
203
+ const script = path.join(target, "base", "scripts", "edusquads_onboarding_memoria.py");
204
+ if (!fs.existsSync(script)) {
205
+ console.log("\n⚠️ Script de onboarding não encontrado. Pule e rode manualmente depois.");
206
+ return;
207
+ }
208
+
209
+ const pyCmd = process.platform === "win32" ? "python" : "python3";
210
+ const r = spawnSync(pyCmd, [script, "--target", target], {
211
+ stdio: "inherit",
212
+ cwd: target,
213
+ env: process.env,
214
+ });
215
+
216
+ if (r.status !== 0) {
217
+ console.log("\n⚠️ Não foi possível concluir o onboarding automaticamente.");
218
+ console.log("Rode manualmente:");
219
+ console.log(` ${pyCmd} base/scripts/edusquads_onboarding_memoria.py --target ${target}`);
220
+ }
221
+ }
222
+
168
223
  async function resolveIdes() {
169
224
  if (ideArg) return parseIdes(ideArg);
170
225
 
@@ -172,15 +227,15 @@ async function resolveIdes() {
172
227
  return ["claude"];
173
228
  }
174
229
 
175
- console.log("\nSelecione a(s) IDE(s) para instalar o EduSquads:");
176
- console.log(" 1) claude (Claude Code)");
177
- console.log(" 2) codex");
178
- console.log(" 3) opencode");
179
- console.log(" 4) kilocode");
180
- console.log(" 5) antigravity");
181
- console.log(" 6) all (todas)");
230
+ panel("EduSquads · Seleção de IDE");
231
+ console.log(`${style(" 1)", UI.cyan)} claude ${style("(Claude Code)", UI.dim)}`);
232
+ console.log(`${style(" 2)", UI.cyan)} codex`);
233
+ console.log(`${style(" 3)", UI.cyan)} opencode`);
234
+ console.log(`${style(" 4)", UI.cyan)} kilocode`);
235
+ console.log(`${style(" 5)", UI.cyan)} antigravity`);
236
+ console.log(`${style(" 6)", UI.cyan)} all ${style("(todas)", UI.dim)}`);
182
237
 
183
- const answer = (await ask("Digite número(s) separados por vírgula (default: 1): ")).trim();
238
+ const answer = (await ask(`${style("\n→", UI.cyan, UI.bold)} Digite número(s) separados por vírgula ${style("[default: 1]", UI.dim)}: `)).trim();
184
239
  if (!answer) return ["claude"];
185
240
 
186
241
  const numberMap = {
@@ -240,14 +295,21 @@ async function install() {
240
295
  const gitignoreChanged = patchGitignore(targetDir);
241
296
  writeInstallMarker(targetDir, ides);
242
297
 
243
- console.log(`\nEduSquads ${dryRun ? "(simulação) " : ""}instalado em: ${targetDir}`);
244
- console.log(`IDEs instaladas: ${ides.join(", ")}`);
245
- console.log(`Arquivos criados: ${report.created}`);
246
- console.log(`Arquivos sobrescritos: ${report.overwritten}`);
247
- console.log(`Arquivos ignorados ( existiam): ${report.skipped}`);
248
- console.log(`.gitignore atualizado: ${gitignoreChanged ? "sim" : "não"}`);
298
+ panel("EduSquads · Instalação concluída");
299
+ console.log(`${style("✔", UI.green, UI.bold)} destino: ${targetDir}`);
300
+ console.log(`${style("✔", UI.green, UI.bold)} IDEs: ${ides.join(", ")}`);
301
+ console.log(`${style("•", UI.cyan)} criados: ${report.created}`);
302
+ console.log(`${style("•", UI.cyan)} sobrescritos: ${report.overwritten}`);
303
+ console.log(`${style("", UI.cyan)} ignorados: ${report.skipped}`);
304
+ console.log(`${style("•", UI.cyan)} .gitignore atualizado: ${gitignoreChanged ? "sim" : "não"}`);
305
+
306
+ const doOnboarding = await askOnboarding();
307
+ if (doOnboarding) {
308
+ console.log(`\n${style("→", UI.cyan, UI.bold)} Iniciando briefing guiado...\n`);
309
+ runOnboarding(targetDir);
310
+ }
249
311
 
250
- console.log("\nComandos esperados por IDE (após abrir o projeto na IDE):");
312
+ console.log(`\n${style("Próximo passo", UI.bold)}:`);
251
313
  for (const ide of ides) {
252
314
  if (ide === "claude") console.log("- Claude Code: /edusquads");
253
315
  else console.log(`- ${ide}: skill 'edusquads' instalada em ${IDE_SKILL_PATHS[ide]}`);
package/carrosseis.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  Voce e um agente especializado em criar carrosseis profissionais para o Instagram no estilo editorial/investigativo inspirado em [PERFIL_INSPIRACAO] e perfis de growth/conteudo viral. Todos os carrosseis sao de autoria do **[SEU_INSTAGRAM]** e tem como tema principal **Inteligencia Artificial**.
4
4
 
5
+ ## Pre-check obrigatorio (antes de qualquer criacao)
6
+
7
+ Antes de iniciar, **sempre** coletar e validar as credenciais da pessoa usuaria:
8
+
9
+ - `APIFY_API_TOKEN` (para pesquisa de tendencias no Reddit)
10
+ - `UNSPLASH_ACCESS_KEY` (para busca de fotos)
11
+
12
+ Regras:
13
+ - Nao iniciar roteiro, HTML ou imagens sem essas duas chaves.
14
+ - Se alguma chave faltar, pausar e pedir a chave primeiro.
15
+ - Nunca expor a chave em resposta, log, markdown ou print.
16
+ - Quando o ambiente suportar coleta segura, usar fluxo seguro de segredo (ex.: coleta mascarada).
17
+
5
18
  ---
6
19
 
7
20
  ## Identidade Visual (Estilo Editorial/Investigativo)
@@ -243,7 +256,7 @@ Use a API do Apify para acessar o Reddit e encontrar topicos em alta sobre **Int
243
256
 
244
257
  ```bash
245
258
  # Buscar posts trending no Reddit sobre IA
246
- curl -X POST "https://api.apify.com/v2/acts/trudax~reddit-scraper/runs?token=apify_api_nRqx0LcknCK9HAkJChOYhLlAgzmNkf2eh8cE" \
259
+ curl -X POST "https://api.apify.com/v2/acts/trudax~reddit-scraper/runs?token=${APIFY_API_TOKEN}" \
247
260
  -H "Content-Type: application/json" \
248
261
  -d '{
249
262
  "startUrls": [
@@ -266,7 +279,7 @@ Depois, busque os resultados:
266
279
 
267
280
  ```bash
268
281
  # Verificar status e buscar resultados
269
- curl "https://api.apify.com/v2/acts/trudax~reddit-scraper/runs/last/dataset/items?token=apify_api_nRqx0LcknCK9HAkJChOYhLlAgzmNkf2eh8cE"
282
+ curl "https://api.apify.com/v2/acts/trudax~reddit-scraper/runs/last/dataset/items?token=${APIFY_API_TOKEN}"
270
283
  ```
271
284
 
272
285
  **Subreddits de IA recomendados:**
@@ -288,7 +301,7 @@ Analise os posts com mais engajamento e extraia:
288
301
 
289
302
  ```bash
290
303
  # Buscar imagens relevantes ao tema
291
- curl -H "Authorization: Client-ID [SUA_UNSPLASH_ACCESS_KEY]" \
304
+ curl -H "Authorization: Client-ID ${UNSPLASH_ACCESS_KEY}" \
292
305
  "https://api.unsplash.com/search/photos?query=TEMA_AQUI&per_page=10&orientation=portrait"
293
306
  ```
294
307
 
@@ -955,6 +968,7 @@ Siga [SEU_INSTAGRAM] para mais conteudo sobre IA.
955
968
 
956
969
  Quando o usuario pedir para criar um carrossel, siga este fluxo:
957
970
 
971
+ 0. **Coletar e validar credenciais** (`APIFY_API_TOKEN` e `UNSPLASH_ACCESS_KEY`)
958
972
  1. **Pesquise tendencias de IA** no Reddit usando Apify API
959
973
  2. **Escolha o tema** mais relevante/viral encontrado
960
974
  3. **Crie o roteiro** com titulos investigativos e textos para cada slide
@@ -970,19 +984,23 @@ Quando o usuario pedir para criar um carrossel, siga este fluxo:
970
984
 
971
985
  ### Unsplash API
972
986
  - **Endpoint**: `https://api.unsplash.com/search/photos`
973
- - **Header**: `Authorization: Client-ID [SUA_UNSPLASH_ACCESS_KEY]`
974
- - **Application ID**: `904033`
975
- - **Access Key**: `[SUA_UNSPLASH_ACCESS_KEY]`
976
- - **Secret Key**: `[SUA_UNSPLASH_SECRET_KEY]`
977
- - **Redirect URI**: `urn:ietf:wg:oauth:2.0:oob`
987
+ - **Header**: `Authorization: Client-ID ${UNSPLASH_ACCESS_KEY}`
988
+ - **Variavel obrigatoria**: `UNSPLASH_ACCESS_KEY`
989
+ - **Opcional**: `UNSPLASH_SECRET_KEY` (nao necessaria para busca publica de fotos)
978
990
  - **Docs**: https://unsplash.com/documentation
979
991
  - **Campo de URL para slides**: `results[n].urls.regular` (1080px)
980
992
 
981
993
  ### Apify (Reddit Scraper)
982
- - **Token**: `apify_api_nRqx0LcknCK9HAkJChOYhLlAgzmNkf2eh8cE`
994
+ - **Token**: `${APIFY_API_TOKEN}`
995
+ - **Variavel obrigatoria**: `APIFY_API_TOKEN`
983
996
  - **Actor**: `trudax~reddit-scraper`
984
997
  - **Endpoint base**: `https://api.apify.com/v2/acts/trudax~reddit-scraper/runs`
985
998
 
986
999
  ### Playwright MCP
987
1000
  - Usar para renderizar HTML e capturar screenshots dos slides
988
1001
  - Viewport: 1080x1350 (formato Instagram 4:5)
1002
+
1003
+ ### Politica de seguranca
1004
+ - Nunca escrever chaves em markdown, codigo fonte, logs ou resposta final.
1005
+ - Nunca usar token fixo/hardcoded no comando.
1006
+ - Se faltar credencial, interromper e solicitar antes de continuar.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edusquads-cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Instalador do framework EduSquads para Claude Code via npx.",
5
5
  "bin": {
6
6
  "edusquads": "bin/edusquads.js"
@@ -0,0 +1,60 @@
1
+ # Skill: Refinar ICP
2
+
3
+ ## objetivo
4
+ Refinar o público inicial informado pela pessoa usuária em um ICP operacional, específico e acionável para conteúdo, oferta e aquisição.
5
+
6
+ ## quando usar
7
+ - quando o briefing tiver público genérico (ex.: "empreendedores", "empresas")
8
+ - quando a mensagem estiver ampla demais
9
+ - antes de gerar plano de conteúdo, copy ou tráfego
10
+
11
+ ## quando não usar
12
+ - quando o usuário já trouxer ICP específico validado recentemente
13
+ - quando a tarefa não exigir definição de público
14
+
15
+ ## entradas
16
+ - o que a pessoa faz
17
+ - o que vende
18
+ - onde vende
19
+ - meta principal (30-90 dias)
20
+ - formato favorito
21
+ - público inicial (rascunho)
22
+
23
+ ## processo
24
+ 1. Identificar quem compra hoje vs. quem a pessoa gostaria de atrair.
25
+ 2. Mapear dor principal, contexto e nível de consciência do público.
26
+ 3. Delimitar recorte de ICP por cenário de compra (canal + momento + problema).
27
+ 4. Redigir ICP em linguagem objetiva (quem é, dor, objetivo, objeção, gatilho de compra).
28
+ 5. Gerar 3 variações de ICP (foco conservador, foco principal, foco expansão).
29
+ 6. Recomendar ICP prioritário com justificativa curta.
30
+
31
+ ## saída
32
+ - ICP prioritário (1 parágrafo)
33
+ - 3 variações de ICP (bullets)
34
+ - sinais de validação inicial (o que observar em 2-4 semanas)
35
+ - ajustes de mensagem por formato favorito
36
+
37
+ ## critérios
38
+ - específico o suficiente para segmentação prática
39
+ - coerente com o que a pessoa vende e onde vende
40
+ - linguagem simples, sem jargão desnecessário
41
+ - aplicável em conteúdo/copy/oferta imediatamente
42
+
43
+ ## fundamento
44
+ Inspirado em princípios publicamente associados a April Dunford (posicionamento), Joanna Wiebe (voz do cliente) e Donald Miller (clareza de mensagem).
45
+
46
+ ## heurísticas
47
+ - "genérico" não é ICP: sempre exigir recorte de contexto
48
+ - priorizar dor concreta sobre atributo demográfico isolado
49
+ - ICP bom facilita decisão editorial e comercial na mesma direção
50
+
51
+ ## anti-padrões
52
+ - ICP amplo demais ("todo mundo")
53
+ - foco em persona estética sem dor/comportamento de compra
54
+ - trocar ICP a cada semana sem evidência
55
+
56
+ ## fontes
57
+ - `especialistas/posicionamento/april-dunford.md`
58
+ - `especialistas/copy/joanna-wiebe.md`
59
+ - `especialistas/mensagem/donald-miller.md`
60
+ - `base/protocolo-memoria-usuario.md`