edusquads-cli 0.2.2 → 0.2.4
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/skills/edusquads/SKILL.md +20 -20
- package/README.md +13 -1
- package/_edusquads/memoria/USUARIO-ATIVO.md +16 -25
- package/base/comandos/edusquads-comandos.md +4 -1
- package/base/protocolo-memoria-usuario.md +26 -29
- package/base/scripts/edusquads_onboarding_memoria.py +100 -56
- package/bin/edusquads.js +42 -17
- package/carrosseis.md +27 -9
- package/package.json +1 -1
- package/squads/02-pesquisa/skills/refinar-icp.md +60 -0
- package/base/scripts/__pycache__/edusquads_onboarding_memoria.cpython-312.pyc +0 -0
|
@@ -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.
|
|
38
|
-
4.
|
|
39
|
-
5.
|
|
40
|
-
6.
|
|
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)
|
|
@@ -94,28 +95,27 @@ Operar squads multiagente no Claude Code com comportamento semelhante ao OpenSqu
|
|
|
94
95
|
|
|
95
96
|
### Campos críticos
|
|
96
97
|
- nome preferido
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
- oferta principal (ou hipótese)
|
|
98
|
+
- o que a pessoa faz
|
|
99
|
+
- onde vende
|
|
100
|
+
- meta principal (30-90 dias)
|
|
101
|
+
- formato favorito
|
|
102
|
+
- público inicial (rascunho)
|
|
103
103
|
|
|
104
104
|
### Fluxo de memória
|
|
105
105
|
1. Ler memória ativa.
|
|
106
|
-
2. Se campo crítico faltar, iniciar onboarding
|
|
106
|
+
2. Se campo crítico faltar, iniciar onboarding enxuto.
|
|
107
107
|
3. Salvar briefing no perfil individual (`usuarios/<slug>.md`).
|
|
108
108
|
4. Atualizar `USUARIO-ATIVO.md` com o briefing coletado.
|
|
109
|
-
5.
|
|
109
|
+
5. Refinar público com skill ICP (`squads/02-pesquisa/skills/refinar-icp.md`).
|
|
110
|
+
6. Só então propor plano de squads.
|
|
110
111
|
|
|
111
112
|
### Roteiro de briefing obrigatório
|
|
112
|
-
1.
|
|
113
|
-
2.
|
|
114
|
-
3.
|
|
115
|
-
4.
|
|
116
|
-
5.
|
|
117
|
-
6.
|
|
118
|
-
7. stack, ativos e dados disponíveis
|
|
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`)
|
|
119
119
|
|
|
120
120
|
## Modo de comando `/edusquads`
|
|
121
121
|
Interpretar intenção do usuário por subcomando semântico.
|
|
@@ -125,7 +125,7 @@ Interpretar intenção do usuário por subcomando semântico.
|
|
|
125
125
|
|
|
126
126
|
### `/edusquads init`
|
|
127
127
|
- Inicia onboarding do usuário.
|
|
128
|
-
- Coleta briefing
|
|
128
|
+
- Coleta briefing enxuto e salva perfil + usuário ativo.
|
|
129
129
|
|
|
130
130
|
### `/edusquads onboarding`
|
|
131
131
|
- Força nova coleta de briefing para troca/atualização de usuário.
|
package/README.md
CHANGED
|
@@ -33,7 +33,16 @@ npx edusquads-cli install --skip-onboarding
|
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
Após instalar, o CLI pergunta no terminal se a pessoa quer preencher o briefing na hora.
|
|
36
|
-
Se aceitar, ele executa onboarding e grava a memória automaticamente.
|
|
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.
|
|
37
46
|
|
|
38
47
|
|
|
39
48
|
Depois da instalação, abra o projeto no Claude Code e use:
|
|
@@ -49,6 +58,7 @@ Como o Claude Code suporta skills em `.claude/skills/<nome>/SKILL.md`, a skill `
|
|
|
49
58
|
- `squads/`: definição dos squads e agentes oficiais
|
|
50
59
|
- `pesquisa/web/`: sínteses com fontes públicas
|
|
51
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
|
|
52
62
|
- `_edusquads/runs/`: histórico de execuções do `/edusquads`
|
|
53
63
|
- `_edusquads/browser_profile/`: sessão local de navegação (Playwright)
|
|
54
64
|
- `_edusquads/evidencias/`: evidências de investigação web
|
|
@@ -59,6 +69,8 @@ Sistema operacional implementado com foco em:
|
|
|
59
69
|
- comando `/edusquads`
|
|
60
70
|
- paridade funcional base inspirada no OpenSquad
|
|
61
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`)
|
|
62
74
|
- histórico de runs (`_edusquads/runs/`)
|
|
63
75
|
- protocolo de investigação web com Playwright (`base/protocolo-playwright-edusquads.md`)
|
|
64
76
|
- playbooks por plataforma (`base/playbooks/investigacao/`)
|
|
@@ -2,35 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
## Identidade
|
|
4
4
|
- Nome preferido:
|
|
5
|
-
-
|
|
6
|
-
- Papel do usuário:
|
|
5
|
+
- O que a pessoa faz:
|
|
7
6
|
|
|
8
|
-
##
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- Oferta principal:
|
|
12
|
-
- Maturidade da operação (inicial/intermediária/avançada):
|
|
7
|
+
## Negócio e Canal
|
|
8
|
+
- O que vende:
|
|
9
|
+
- Onde vende:
|
|
13
10
|
|
|
14
|
-
##
|
|
15
|
-
-
|
|
16
|
-
- Objetivo secundário:
|
|
17
|
-
- KPI principal:
|
|
11
|
+
## Meta principal
|
|
12
|
+
- Meta (30-90 dias):
|
|
18
13
|
|
|
19
|
-
##
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
- Equipe disponível:
|
|
27
|
-
- Orçamento aproximado:
|
|
28
|
-
- Limites operacionais:
|
|
14
|
+
## Público
|
|
15
|
+
- Público inicial (rascunho):
|
|
16
|
+
- ICP prioritário (refinado):
|
|
17
|
+
- Variações de ICP:
|
|
18
|
+
-
|
|
19
|
+
-
|
|
20
|
+
-
|
|
29
21
|
|
|
30
|
-
##
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- Dados disponíveis:
|
|
22
|
+
## Preferências
|
|
23
|
+
- Formato favorito:
|
|
24
|
+
- Estilo de comunicação preferido:
|
|
34
25
|
|
|
35
26
|
## Histórico de decisões
|
|
36
27
|
- [ ]
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Subcomandos semânticos (via args)
|
|
8
8
|
- `/edusquads init`
|
|
9
|
-
- inicia onboarding e coleta briefing
|
|
9
|
+
- inicia onboarding e coleta briefing enxuto da pessoa usuária
|
|
10
10
|
- salva perfil em `_edusquads/memoria/usuarios/` e atualiza `USUARIO-ATIVO.md`
|
|
11
11
|
- `/edusquads onboarding`
|
|
12
12
|
- força nova coleta de briefing para troca/atualização de usuário
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
- resume estado dos squads, memória e artefatos
|
|
15
15
|
- `/edusquads memoria`
|
|
16
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`)
|
|
17
19
|
- `/edusquads squads`
|
|
18
20
|
- lista os 16 squads e indica quais usar no objetivo atual
|
|
19
21
|
- `/edusquads plano <objetivo>`
|
|
@@ -42,6 +44,7 @@
|
|
|
42
44
|
- todos os subcomandos usam `_edusquads/memoria/USUARIO-ATIVO.md`
|
|
43
45
|
- onboarding é obrigatório quando memória crítica estiver vazia
|
|
44
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`
|
|
45
48
|
- onboarding deve salvar perfil em `_edusquads/memoria/usuarios/` e atualizar `USUARIO-ATIVO.md`
|
|
46
49
|
- cada execução relevante deve gerar/atualizar um run em `_edusquads/runs/`
|
|
47
50
|
- toda investigação web deve seguir `base/protocolo-playwright-edusquads.md`
|
|
@@ -10,46 +10,43 @@ Manter uma memória operacional da pessoa usuária para personalizar a atuação
|
|
|
10
10
|
|
|
11
11
|
## Quando coletar memória
|
|
12
12
|
1. Primeira execução do `/edusquads` no projeto
|
|
13
|
-
2. Quando
|
|
14
|
-
3. Quando
|
|
13
|
+
2. Quando houver troca de usuário
|
|
14
|
+
3. Quando a pessoa pedir atualização de contexto
|
|
15
15
|
|
|
16
16
|
## Princípios
|
|
17
|
-
- coletar
|
|
18
|
-
-
|
|
19
|
-
-
|
|
17
|
+
- coletar somente dados úteis para execução
|
|
18
|
+
- manter briefing enxuto
|
|
19
|
+
- não pedir KPI técnico no onboarding inicial
|
|
20
20
|
- nunca registrar segredos/token/senhas na memória
|
|
21
21
|
|
|
22
22
|
## Regras de uso no comando
|
|
23
23
|
- antes de planejar squads, ler `USUARIO-ATIVO.md`
|
|
24
|
-
- se campos críticos estiverem vazios, executar onboarding
|
|
24
|
+
- se campos críticos estiverem vazios, executar onboarding enxuto
|
|
25
25
|
- salvar briefing no perfil individual e atualizar o usuário ativo
|
|
26
|
-
-
|
|
26
|
+
- após onboarding, refinar público com skill ICP
|
|
27
27
|
|
|
28
28
|
## Campos críticos (não seguir sem isso)
|
|
29
29
|
- nome preferido
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
6. Quais restrições de tempo/equipe/orçamento existem
|
|
44
|
-
7. Quais ferramentas, ativos e dados já existem
|
|
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`)
|
|
45
43
|
|
|
46
44
|
## Formato de atualização
|
|
47
45
|
Sempre atualizar por bloco:
|
|
48
46
|
1. `## Identidade`
|
|
49
|
-
2. `##
|
|
50
|
-
3. `##
|
|
51
|
-
4. `##
|
|
52
|
-
5. `##
|
|
53
|
-
6. `##
|
|
54
|
-
7. `##
|
|
55
|
-
8. `## Última atualização`
|
|
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`
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
Onboarding de memória do EduSquads.
|
|
3
|
+
Onboarding enxuto de memória do EduSquads.
|
|
4
4
|
|
|
5
|
-
Coleta briefing
|
|
5
|
+
Coleta briefing essencial e salva em:
|
|
6
6
|
- _edusquads/memoria/USUARIO-ATIVO.md
|
|
7
7
|
- _edusquads/memoria/usuarios/<slug>.md
|
|
8
8
|
"""
|
|
@@ -14,13 +14,32 @@ import datetime as dt
|
|
|
14
14
|
import re
|
|
15
15
|
from pathlib import Path
|
|
16
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"
|
|
17
23
|
|
|
18
|
-
|
|
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}")
|
|
19
38
|
while True:
|
|
20
39
|
value = input(f"{prompt}: ").strip()
|
|
21
40
|
if value or not required:
|
|
22
41
|
return value
|
|
23
|
-
print("Campo obrigatório.
|
|
42
|
+
print(f"{YELLOW}Campo obrigatório. Responda para continuar.{RESET}")
|
|
24
43
|
|
|
25
44
|
|
|
26
45
|
def slugify(text: str) -> str:
|
|
@@ -31,44 +50,59 @@ def slugify(text: str) -> str:
|
|
|
31
50
|
return t or "usuario"
|
|
32
51
|
|
|
33
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
|
+
|
|
34
74
|
def render_memory(data: dict, source: str) -> str:
|
|
35
75
|
today = dt.date.today().isoformat()
|
|
76
|
+
icp_prioritario, variacoes = refine_icp(data)
|
|
77
|
+
|
|
36
78
|
return f"""# Memória do Usuário Ativo
|
|
37
79
|
|
|
38
80
|
## Identidade
|
|
39
81
|
- Nome preferido: {data['nome']}
|
|
40
|
-
-
|
|
41
|
-
- Papel do usuário: {data['papel']}
|
|
42
|
-
|
|
43
|
-
## Estado atual
|
|
44
|
-
- Nicho principal: {data['nicho']}
|
|
45
|
-
- Público-alvo: {data['publico']}
|
|
46
|
-
- Oferta principal: {data['oferta']}
|
|
47
|
-
- Maturidade da operação (inicial/intermediária/avançada): {data['maturidade']}
|
|
82
|
+
- O que a pessoa faz: {data['o_que_faz']}
|
|
48
83
|
|
|
49
|
-
##
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
- KPI principal: {data['kpi']}
|
|
84
|
+
## Negócio e Canal
|
|
85
|
+
- O que vende: {data['o_que_vende']}
|
|
86
|
+
- Onde vende: {data['onde_vende']}
|
|
53
87
|
|
|
54
|
-
##
|
|
55
|
-
-
|
|
56
|
-
- Estilo de comunicação: {data['estilo']}
|
|
57
|
-
- Formato de entrega preferido: {data['formato_entrega']}
|
|
88
|
+
## Meta principal
|
|
89
|
+
- Meta (30-90 dias): {data['meta_90_dias']}
|
|
58
90
|
|
|
59
|
-
##
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
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]}
|
|
64
98
|
|
|
65
|
-
##
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- Dados disponíveis: {data['dados']}
|
|
99
|
+
## Preferências
|
|
100
|
+
- Formato favorito: {data['formato_favorito']}
|
|
101
|
+
- Estilo de comunicação preferido: {data['estilo']}
|
|
69
102
|
|
|
70
103
|
## Histórico de decisões
|
|
71
|
-
- [x] briefing inicial coletado no onboarding
|
|
104
|
+
- [x] briefing inicial coletado no onboarding enxuto
|
|
105
|
+
- [x] público refinado via skill de ICP (`squads/02-pesquisa/skills/refinar-icp.md`)
|
|
72
106
|
|
|
73
107
|
## Última atualização
|
|
74
108
|
- Data: {today}
|
|
@@ -77,7 +111,7 @@ def render_memory(data: dict, source: str) -> str:
|
|
|
77
111
|
|
|
78
112
|
|
|
79
113
|
def main() -> int:
|
|
80
|
-
parser = argparse.ArgumentParser(description="Onboarding de memória EduSquads")
|
|
114
|
+
parser = argparse.ArgumentParser(description="Onboarding enxuto de memória EduSquads")
|
|
81
115
|
parser.add_argument("--target", default=".", help="Diretório do projeto")
|
|
82
116
|
args = parser.parse_args()
|
|
83
117
|
|
|
@@ -87,44 +121,54 @@ def main() -> int:
|
|
|
87
121
|
mem_dir.mkdir(parents=True, exist_ok=True)
|
|
88
122
|
users_dir.mkdir(parents=True, exist_ok=True)
|
|
89
123
|
|
|
90
|
-
|
|
91
|
-
print("
|
|
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}")
|
|
92
147
|
|
|
93
148
|
data = {
|
|
94
|
-
"nome":
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"objetivo_secundario": ask("Objetivo secundário", required=False) or "não informado",
|
|
103
|
-
"kpi": ask("KPI principal", required=False) or "não informado",
|
|
104
|
-
"canais": ask("Canais prioritários", required=False) or "não informado",
|
|
105
|
-
"estilo": ask("Estilo de comunicação preferido", required=False) or "não informado",
|
|
106
|
-
"formato_entrega": ask("Formato de entrega preferido", required=False) or "não informado",
|
|
107
|
-
"tempo": ask("Tempo disponível", required=False) or "não informado",
|
|
108
|
-
"equipe": ask("Equipe disponível", required=False) or "não informado",
|
|
109
|
-
"orcamento": ask("Orçamento aproximado", required=False) or "não informado",
|
|
110
|
-
"limites": ask("Limites operacionais", required=False) or "não informado",
|
|
111
|
-
"ferramentas": ask("Ferramentas atuais", required=False) or "não informado",
|
|
112
|
-
"ativos": ask("Ativos existentes (lista/email/site/perfis)", required=False) or "não informado",
|
|
113
|
-
"dados": ask("Dados disponíveis", required=False) or "não informado",
|
|
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,
|
|
114
157
|
}
|
|
115
158
|
|
|
116
|
-
content = render_memory(data, source="onboarding-interativo")
|
|
159
|
+
content = render_memory(data, source="onboarding-enxuto-interativo")
|
|
117
160
|
|
|
118
161
|
active_path = mem_dir / "USUARIO-ATIVO.md"
|
|
119
162
|
active_path.write_text(content, encoding="utf-8")
|
|
120
163
|
|
|
121
|
-
slug = slugify(
|
|
164
|
+
slug = slugify(nome)
|
|
122
165
|
profile_path = users_dir / f"{slug}.md"
|
|
123
166
|
profile_path.write_text(content, encoding="utf-8")
|
|
124
167
|
|
|
125
|
-
print("\n✅ Briefing salvo com sucesso
|
|
168
|
+
print(f"\n{GREEN}✅ Briefing salvo com sucesso{RESET}")
|
|
126
169
|
print(f"- ativo: {active_path}")
|
|
127
170
|
print(f"- perfil: {profile_path}")
|
|
171
|
+
print(f"- icp skill: squads/02-pesquisa/skills/refinar-icp.md\n")
|
|
128
172
|
return 0
|
|
129
173
|
|
|
130
174
|
|
package/bin/edusquads.js
CHANGED
|
@@ -5,6 +5,28 @@ const path = require("path");
|
|
|
5
5
|
const readline = require("readline");
|
|
6
6
|
const { spawnSync } = require("child_process");
|
|
7
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
|
+
}
|
|
29
|
+
|
|
8
30
|
const args = process.argv.slice(2);
|
|
9
31
|
const command = args.find((a) => !a.startsWith("-")) || "install";
|
|
10
32
|
const force = args.includes("--force");
|
|
@@ -36,6 +58,8 @@ const SHARED_INSTALL_ITEMS = [
|
|
|
36
58
|
{ src: "pesquisa", dest: "pesquisa" },
|
|
37
59
|
{ src: "squads", dest: "squads" },
|
|
38
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" },
|
|
39
63
|
{ src: "_edusquads/runs/RUN-MODELO.md", dest: "_edusquads/runs/RUN-MODELO.md" },
|
|
40
64
|
{ src: "_edusquads/runs/RUNS-INDEX.md", dest: "_edusquads/runs/RUNS-INDEX.md" },
|
|
41
65
|
{ src: "_edusquads/evidencias/EVIDENCIA-MODELO.md", dest: "_edusquads/evidencias/EVIDENCIA-MODELO.md" },
|
|
@@ -171,7 +195,7 @@ function ask(promptText) {
|
|
|
171
195
|
async function askOnboarding() {
|
|
172
196
|
if (skipOnboarding || dryRun) return false;
|
|
173
197
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
|
|
174
|
-
const ans = (await ask("Deseja
|
|
198
|
+
const ans = (await ask(`${style("\n→", UI.cyan, UI.bold)} Deseja iniciar o briefing guiado agora? ${style("(s/N)", UI.dim)} `)).trim().toLowerCase();
|
|
175
199
|
return ["s", "sim", "y", "yes"].includes(ans);
|
|
176
200
|
}
|
|
177
201
|
|
|
@@ -203,15 +227,15 @@ async function resolveIdes() {
|
|
|
203
227
|
return ["claude"];
|
|
204
228
|
}
|
|
205
229
|
|
|
206
|
-
|
|
207
|
-
console.log(" 1) claude (Claude Code)");
|
|
208
|
-
console.log(" 2) codex
|
|
209
|
-
console.log(" 3) opencode
|
|
210
|
-
console.log(" 4) kilocode
|
|
211
|
-
console.log(" 5) antigravity
|
|
212
|
-
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)}`);
|
|
213
237
|
|
|
214
|
-
const answer = (await ask("Digite número(s) separados por vírgula (default: 1):
|
|
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();
|
|
215
239
|
if (!answer) return ["claude"];
|
|
216
240
|
|
|
217
241
|
const numberMap = {
|
|
@@ -271,20 +295,21 @@ async function install() {
|
|
|
271
295
|
const gitignoreChanged = patchGitignore(targetDir);
|
|
272
296
|
writeInstallMarker(targetDir, ides);
|
|
273
297
|
|
|
274
|
-
|
|
275
|
-
console.log(
|
|
276
|
-
console.log(
|
|
277
|
-
console.log(
|
|
278
|
-
console.log(
|
|
279
|
-
console.log(
|
|
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"}`);
|
|
280
305
|
|
|
281
306
|
const doOnboarding = await askOnboarding();
|
|
282
307
|
if (doOnboarding) {
|
|
283
|
-
console.log("
|
|
308
|
+
console.log(`\n${style("→", UI.cyan, UI.bold)} Iniciando briefing guiado...\n`);
|
|
284
309
|
runOnboarding(targetDir);
|
|
285
310
|
}
|
|
286
311
|
|
|
287
|
-
console.log("
|
|
312
|
+
console.log(`\n${style("Próximo passo", UI.bold)}:`);
|
|
288
313
|
for (const ide of ides) {
|
|
289
314
|
if (ide === "claude") console.log("- Claude Code: /edusquads");
|
|
290
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
|
|
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
|
|
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
|
|
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
|
|
974
|
-
- **
|
|
975
|
-
- **
|
|
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**: `
|
|
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
|
@@ -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`
|
|
Binary file
|