Jobmaker-LdPost/INSTRUCOES.md
Ricardo Carneiro ea532659b0 feat: pipeline inicial ldpost-squad (6 agentes)
Pipeline completo de publicação no LinkedIn:
evaluator → redator → editor → art → director → publisher

- Seed com 37 posts em _sugestoes.md
- Sorteio de formato com N=3 bloqueados (format-history)
- Reciclagem mensal de posts com rotação de formato
- Revisão via Telegram com chat livre (Gemini 2.5 Flash)
- Publicação via LinkedIn API (OAuth2)
- Makefile com targets para Windows/Linux/ARM64

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 18:55:39 -03:00

180 lines
5.0 KiB
Markdown

# ldpost-squad — Instruções Gerais
---
## Princípio Central: Testabilidade Independente
**Cada CLI deve rodar de forma isolada, sem depender que outro CLI tenha rodado antes.**
Regras:
- Toda CLI aceita `--post <slug>` como entrada principal
- Toda CLI aceita `--dry-run` para operar sem side effects (sem salvar arquivo, sem chamar API externa)
- Toda CLI pode ser testada com um fixture manual (arquivo criado à mão no workspace)
- Nenhuma CLI assume estado global — lê e escreve apenas no workspace do post
---
## Workspace Layout
```
$LDPOST_WORKSPACE/
<slug>/
post.json ← metadados: tema, formato, imagens desc, status
draft.md ← rascunho cru (gerado pelo redator)
final.md ← versão formatada LinkedIn (gerado pelo editor)
img/
cover.png ← imagem principal
slide-*.png ← slides do carrossel (se aplicável)
status.json ← pipeline state: pending|approved|published + URL
```
**Como testar qualquer CLI isoladamente:**
```bash
# Crie o fixture mínimo manualmente
mkdir -p "$LDPOST_WORKSPACE/meu-slug"
echo '{"slug":"meu-slug","topic":"IA no RH","format":"lista"}' \
> "$LDPOST_WORKSPACE/meu-slug/post.json"
# Agora rode qualquer CLI contra esse slug
ldpost-redator --post meu-slug --dry-run
ldpost-editor --post meu-slug --no-interactive
ldpost-art --post meu-slug --dry-run
ldpost-director --post meu-slug --skip-telegram
ldpost-publisher --post meu-slug --dry-run
```
---
## Variáveis de Ambiente
Arquivo `.env` na raiz do workspace **ou** exportadas no shell.
```env
# Obrigatórias
GROQ_API_KEY= # modelo rápido (redator, evaluator)
GEMINI_API_KEY= # imagens e análise (art, editor)
LDPOST_WORKSPACE=C:\Textos-LinkedIn
# Telegram (director)
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=
# LinkedIn (publisher) — opcional, fallback manual
LINKEDIN_ACCESS_TOKEN=
LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=
```
Cada CLI deve chamar `godotenv.Load()` no init para carregar `.env` automaticamente se presente.
---
## Estrutura de Módulo Go
Cada CLI é um módulo Go **independente** dentro de `C:\gocode\jobmaker-ldpost\`:
```
jobmaker-ldpost/
shared/ ← módulo compartilhado (go.mod: ldpost/shared)
evaluator/ ← go.mod: ldpost/evaluator
redator/ ← go.mod: ldpost/redator
editor/ ← go.mod: ldpost/editor
art/ ← go.mod: ldpost/art
director/ ← go.mod: ldpost/director
publisher/ ← go.mod: ldpost/publisher
```
CLIs dependem de `ldpost/shared` via `replace` no `go.mod`:
```
require ldpost/shared v0.0.0
replace ldpost/shared => ../shared
```
---
## Convenções de Código
### Flags padrão (toda CLI implementa)
| Flag | Tipo | Descrição |
|------|------|-----------|
| `--post` | string | Slug do post (obrigatória na maioria) |
| `--dry-run` | bool | Opera sem salvar/publicar |
| `--model` | string | Override do modelo LLM |
| `--workspace` | string | Override de `LDPOST_WORKSPACE` |
| `--verbose` | bool | Log detalhado |
### Saída padrão
- Sucesso: imprime caminho do arquivo gerado ou URL publicada
- Erro: `fmt.Fprintf(os.Stderr, "erro: %v\n", err)` + `os.Exit(1)`
- Dry-run: imprime conteúdo que seria gerado/enviado
### Arquivo `post.json` (schema mínimo)
```json
{
"slug": "ia-no-rh-2026",
"topic": "IA no recrutamento em 2026",
"format": "lista",
"images": [
{"index": 1, "prompt": "robô entrevistando humano, estilo flat design"},
{"index": 2, "prompt": "dashboard de triagem de currículos com IA"}
],
"created_at": "2026-05-02T11:00:00Z"
}
```
### Arquivo `status.json`
```json
{
"slug": "ia-no-rh-2026",
"pipeline_status": "pending",
"steps_completed": ["evaluated", "drafted", "edited"],
"approved_at": null,
"published_url": null
}
```
---
## Padrões do jobmaker-squad (reutilizar)
Referência: `C:\gocode\jobmaker-squad\`
| Padrão | Onde está | O que reusar |
|--------|-----------|-------------|
| Gemini API calls | `jobmaker-redator/main.go` | Stream + retry pattern |
| Imagen (geração de imagem) | `jobmaker-art/main.go` | Gemini Imagen 3.0 call |
| Telegram bot | `jobmaker-editor/internal/telegram/` | Keyboard inline, await response |
| Config loader | `jobmaker-editor/internal/config/` | `.env` + flags merge |
| Vector store local | `jobmaker-editor/internal/vectorstore/` | chromem-go pattern |
---
## Como Rodar Testes
```bash
# Cada CLI
cd evaluator && go test ./... -v
# Shared
cd shared && go test ./... -v
# Smoke test completo (requer .env configurado)
./scripts/smoke-test.sh meu-slug
```
---
## Ordem de Implementação
Seguir essa ordem — cada passo desbloqueia o próximo:
1. `shared/` — structs + workspace utils
2. `evaluator/` — sem este, nenhum slug existe
3. `redator/` — depende de `post.json` do evaluator
4. `editor/` — depende de `draft.md` do redator
5. `art/` — depende de `post.json` (descriptions de imagem)
6. `director/` — depende de `final.md` + imagens
7. `publisher/` — depende de `status.json` aprovado
Mas cada um pode ser desenvolvido/testado **isoladamente** com fixtures manuais.