feat: biblioteca inteligente libs/ + 5 novas skills (20 skills total)

NOVAS SKILLS:
- next-best-practices      v0.1.0  (CLEAN) — Next.js App Router, RSC, caching, data
- nextjs-patterns          v1.0.0  (CLEAN) — Next.js 15: Server Actions, route handlers
- vite                     v1.0.0  (CLEAN) — env vars, aliases, proxy, CJS compat
- uncle-bob                v1.0.0  (CLEAN) — Clean Code, SOLID, Clean Architecture
- clean-code-review        v1.0.0  (CLEAN) — naming, guard clauses, anti-patterns, refactoring
- vue                      v1.0.0  (CLEAN) — Vue framework
- vue-composition-api-best-practices v1.0.0 (CLEAN) — composables, Pinia, reactivity

BIBLIOTECA INTELIGENTE libs/ (10 dominios, 11 arquivos):
- typescript/ — TS safe + generics gotchas
- react/ — Next.js App Router + Vite config
- vue/ — Composition API + Pinia
- linux/ — System diagnostic cheatsheet
- database/ — PostgreSQL + MySQL patterns
- browser/ — Chromium CLI + E2E testing
- security/ — SAST audit (OWASP Top 10)
- best-practices/ — Clean Code + SOLID + Clean Architecture
- deploy/ — Docker multi-stack + OpenClaw ops
- + INDEX.md como guia de navegacao

.learnings/ — LRN-20260519-003 criado (biblioteca compartilhada)
This commit is contained in:
Pulse
2026-05-19 21:03:25 -03:00
parent 22d9f5b21d
commit ae39e45460
83 changed files with 13349 additions and 1 deletions
+93
View File
@@ -0,0 +1,93 @@
# 📚 Biblioteca Inteligente — Índice Completo
> Biblioteca dinâmica para compartilhar entre todos os projetos. Conhecimento extraído
> automaticamente das skills instaladas, organizado por domínio.
---
## 🗂️ Estrutura
```
libs/
├── README.md ← Este arquivo
├── typescript/ ← TS seguro: narrowing, generics, satisfies
├── react/ ← Next.js, Vite, App Router, RSC, Server Actions
├── vue/ ← Vue 3 Composition API, Pinia, Router
├── linux/ ← Diagnóstico de sistema, logs, rede, SSH
├── database/ ← PostgreSQL, MySQL — schemas, queries, EXPLAIN
├── browser/ ← Agent-browser (Chromium) + E2E testing
├── security/ ← SAST: OWASP Top 10, prompt injection, secrets
├── best-practices/ ← Clean Code, SOLID, Clean Architecture
├── deploy/ ← Docker multi-stack, xCloud, OpenClaw Gateway
└── docs/ ← Templates de documentação
```
---
## 📁 Typescript — 2 arquivos
| Arquivo | Conteúdo |
|---------|----------|
| `typescript/TYPESCRIPT_SAFE_PATTERNS.md` | narrowing, satisfies, discriminated unions, literais |
| `typescript/GENERICS_UTILITY_GOTCHAS.md` | Armadilhas de generics & utility types `Partial<T>`, `Omit`, `Pick` |
## 📁 React — 2 arquivos
| Arquivo | Conteúdo |
|---------|----------|
| `react/NEXTJS_BEST_PRACTICES.md` | App Router, RSC, Server Actions, caching, data fetching |
| `react/VITE_CONFIG.md` | Env vars, path aliases, Dev Server proxy, CJS compat |
## 📁 Vue — 1 arquivo
| Arquivo | Conteúdo |
|---------|----------|
| `vue/VUE3_COMPOSITION_API.md` | `<script setup>`, composables, Pinia, reactivity, Router traps |
## 📁 Linux — 1 arquivo
| Arquivo | Conteúdo |
|---------|----------|
| `linux/SYSTEM_DIAGNOSTIC.md` | Processes, disk, network, logs, SSH, shell scripts, permissions |
## 📁 Database — 2 arquivos
| Arquivo | Conteúdo |
|---------|----------|
| `database/POSTGRESQL.md` | UUID, JSONB, GIN indexes, CTEs, window functions, EXPLAIN ANALYZE |
| `database/MYSQL.md` | AUTO_INCREMENT, JSON, InnoDB, diferenças vs PostgreSQL |
## 📁 Browser — 2 arquivos
| Arquivo | Conteúdo |
|---------|----------|
| `browser/BROWSER_AUTOMATION.md` | Chromium: navegação, login, persists, screenshot, @refs, dev server proxy |
| `browser/E2E_TESTING.md` | Pirâmide de testes, selectors estáveis, princípios de determinismo |
## 📁 Security — 1 arquivo
| Arquivo | Conteúdo |
|---------|----------|
| `security/SAST_AUDIT.md` | OWASP Top 10, prompt injection, hardcoded secrets, IDOR, SSRF |
## 📁 Best Practices — 1 arquivo
| Arquivo | Conteúdo |
|---------|----------|
| `best-practices/CLEAN_CODE.md` | Naming, functions, SRP, SOLID, Clean Architecture dependency rule |
## 📁 Deploy — 2 arquivos
| Arquivo | Conteúdo |
|---------|----------|
| `deploy/DOCKER_DEPLOY.md` | Stack router, 3 cenários, Dockerfiles pré-prontos, composes template |
| `deploy/OPENCLAW_OPS.md` | CLI cheatsheet, $include modular, Telegram, env vars |
---
## 🔄 Como Usar
### Em cada novo projeto:
1. Copiar `libs/``projeto/docs/dev-standards/`
2. Selecionar pastas relevantes ao stack
3. Consulte antes de implementar cada camada
### Quando o agente codifica:
1. `libs/best-practices/CLEAN_CODE.md` — sempre primeiro
2. `libs/<stack>/` — padrões específicos
3. Aplica automaticamente — não precisa lembrar de cor
### Quando atualizar:
- Nova skill instalada → ler SKILL.md → extrair conhecimento → atualizar `libs/`
- Após cada projeto → feedback → atualizar padrões
+120
View File
@@ -0,0 +1,120 @@
# Clean Code & Architecture — Uncle Bob + SOLID
> Extracted from: `uncle-bob` v1.0.0 + `clean-code-review` v1.0.0
## 🧹 Clean Code — Regras Fundamentais
### Naming (nomes são a melhor documentação)
| Elemento | Convenção | ❌ Errado | ✅ Certo |
|----------|-----------|-----------|--------|
| Variáveis | Revelam intenção | `n`, `d`, `tmp` | `userCount`, `elapsed` |
| Funções | Verbo + substantivo | `user()`, `calc()` | `getUserById()`, `calculateTotal()` |
| Booleanos | Forma de pergunta | `active`, `flag` | `isActive`, `hasPermission`, `canEdit()` |
| Constantes | SNAKE_CASE | `max`, `timeout` | `MAX_RETRY_COUNT`, `REQUEST_TIMEOUT_MS` |
| Classes | Substantivo | `Manager`, `Data` | `UserRepository`, `OrderService` |
> Se precisa de comentário para explicar o nome, o nome está errado.
### Functions — Regras
| Regra | Guia |
|-------|------|
| **Small** | Máx 20 linhas, ideal 5-10 |
| **One Thing** | Faz uma coisa, e faz bem |
| **One Level** | Um nível de abstração por função |
| **Few Args** | Max 3 argumentos, preferir 0-2 |
| **No Side Effects** | Não muta entradas inesperadamente |
### Guard Clauses (evitar ninho profundidade)
```ts
// ❌ 5 níveis de profundidade
function processOrder(order: Order) {
if (order) {
if (order.items.length > 0) {
if (order.total > 0) { ... }
}
}
}
// ✅ Guard clauses — zero aninhamento
function processOrder(order: Order) {
if (!order) return;
if (order.items.length === 0) return;
if (order.total <= 0) return;
// lógica principal aqui
}
```
### SRP — Single Responsibility
> Uma classe tem **um** motivo para mudar. Um ator, uma responsabilidade.
### DRY + YAGNI
- **DRY**: Não duplique — três instâncias de duplicação é o limite para abstrair
- **YAGNI**: Você não vai precisar — não construa features não requisitadas
---
## 🔷 SOLID Principles
| Princípio | Regra Curta |
|-----------|-------------|
| **S** — Single Responsibility | Uma razão para mudar |
| **O** — Open/Closed | Aberto para extensão, fechado para modificação |
| **L** — Liskov Substitution | Subtipo deve ser substituível pelo seu tipo base |
| **I** — Interface Segregation | Muitas interfaces específicas > uma geral |
| **D** — Dependency Inversion | Dependa de abstrações, não de concretudes |
### D — Dependency Inversion Exemplo
```ts
// ❌ Alto nível depende de baixo nível
class ReportGenerator {
private db = new MySQLConnection(); // concreto!
}
// ✅ Depende de abstração
interface Database { query(sql: string): Promise<any[]> }
class ReportGenerator {
constructor(private db: Database) {} // injetado!
}
```
---
## 🏗️ Clean Architecture — Dependency Rule
> Dependências de código apontam **para dentro** — para políticas de mais alto nível.
```
┌─────────────────────────────────────┐
│ Entities / Domain │ ← Nada depende disto
├─────────────────────────────────────┤
│ Use Cases / Business Logic │ ← Só depende de Entities
├─────────────────────────────────────┤
│ Interface Adapters (Controllers) │ ← Só depende de Use Cases
├─────────────────────────────────────┤
│ Frameworks & Drivers (DB, UI) │ ← Tudo depende para dentro
└─────────────────────────────────────┘
```
### Regra da Dependência
```
Código de alto nível → abstração → código de baixo nível
(não pode depender de detalhes)
```
### Quando Usar Clean Architecture
- Projetos com vida útil esperada > 2 anos
- Múltiplas equipes trabalhando no mesmo código
- Possibilidade de trocar framework
- Regras de negócio complexas
## Code Review Checklist (Clean Code)
- [ ] Nomes revelam intenção?
- [ ] Funções fazem uma coisa só?
- [ ] Sem comentários que só recontam o que o código faz?
- [ ] Sem código comentado fora?
- [ ] Sem mais de 3 argumentos em qualquer função?
- [ ] SRP respeitado?
- [ ] DRY aplicado mas sem over-abstração?
- [ ] Tratamento de erros centralizado?
- [ ] Sem uso de `any`/`as any` sem justificativa?
- [ ] O retorno do commit deixa o código melhor do que encontrou? (Boy Scout)
+91
View File
@@ -0,0 +1,91 @@
# Browser Automation — Chromium CLI (agent-browser)
> CLI headless Chromium para navegação, login, raspagem e screenshots.
## Fluxo Padrão
```bash
agent-browser open https://exemplo.com/form
agent-browser snapshot -i # Descobre elementos → @e1, @e2, @e3
agent-browser fill @e1 "user@exemplo.com"
agent-browser fill @e2 "senha123"
agent-browser click @e3
agent-browser wait --load networkidle
agent-browser snapshot -i # Re-snapshot após mudança de DOM
```
## Comandos Essenciais
```bash
# Navegação
agent-browser open <url>
agent-browser close
# Snapshot (sempre primeiro)
agent-browser snapshot -i # Elementos interativos + @refs
agent-browser snapshot -i -C # + cursor-interactive elements
# Interação com @refs
agent-browser click @e1
agent-browser fill @e2 "text" # Clear + type
agent-browser type @e2 "text" # Type sem limpar
agent-browser select @e1 "option"
agent-browser check @e1
agent-browser press Enter
agent-browser scroll down 500
agent-browser hover @e1
# Extração
agent-browser get text @e1
agent-browser get text body > page.txt
agent-browser get html @e1
agent-browser get url
agent-browser get title
# Espera
agent-browser wait @e1
agent-browser wait --load networkidle
agent-browser wait --url "**/dashboard"
# Captura
agent-browser screenshot page.png
agent-browser screenshot --full # Página inteira
agent-browser pdf relatorio.pdf
# Download
agent-browser download @e1 ./file.pdf
agent-browser wait --download ./output.zip
```
## 🔐 Login + Persistência de Sessão
```bash
# Login
agent-browser open https://app.exemplo.com/login
agent-browser fill @e1 "$USERNAME" && agent-browser fill @e2 "$PASSWORD"
agent-browser click @e3
agent-browser wait --url "**/dashboard"
agent-browser state save ~/auth.json # Salva cookies + sessão
# Reutilizar
agent-browser state load ~/auth.json
agent-browser open https://app.exemplo.com/dashboard
```
## 🔒 Segurança (ambiente)
```bash
export AGENT_BROWSER_ALLOWED_DOMAINS="exemplo.com"
export AGENT_BROWSER_MAX_OUTPUT=50000
export AGENT_BROWSER_CONTENT_BOUNDARIES=1
```
## ⚠️ Ref Lifecycle
> Refs (`@e1`, `@e2`) são **invalidados** após qualquer mudança de DOM.
> Sempre faça `snapshot -i` de novo após:
> - Cliques que navegam
> - Submissão de formulário
> - Conteúdo dinâmico (dropdowns, modais)
## Sessões Paralelas
```bash
agent-browser --session site1 open https://site-a.com
agent-browser --session site2 open https://site-b.com
agent-browser session list
```
+37
View File
@@ -0,0 +1,37 @@
# E2E Testing — Pirâmide e Padrões
> Extraído de `e2e-testing-patterns` v1.0.0
## 🏔️ Test Pyramid
```
/\ ← POUCOS: Critical paths (E2E)
/E2E\ ← MAIS: Component/API integration
/─────\
/Integr\ ← MUITOS: Unit tests (rápidos, isolados)
/────────\
/Unit Tests\
/────────────\
```
## O que E2E Tests DEVEM cobrir
| ✅ E2E | ❌ Não E2E |
|--------|-----------|
| Critical journeys (auth → dashboard → logout) | Lógica unitária → use unit tests |
| Multi-step flows (checkout, onboarding) | API contracts → use integration |
| Cross-browser | Edge cases (muito lento) |
| Real API integration | Internal implementation |
| Auth flows | Visual states → use Storybook |
## Core Principles
| Princípio | Como |
|-----------|------|
| **Test behavior, not implementation** | Assert em outcomes visíveis, não estrutura DOM |
| **Independent tests** | Cada teste cria próprios dados e limpa |
| **Deterministic waits** | Esperar por condição, não timeout fixo |
| **Stable selectors** | Usar `data-testid`, roles, labels — nunca CSS classes |
| **Fast feedback** | Mockar serviços externos, paralelizar, shard |
## Selector Priority
```
data-testid → data-cy → role → text → id → class (último recurso)
```
+70
View File
@@ -0,0 +1,70 @@
# MySQL — Patterns e Anti-patterns
> Conexão | Schemas | JSON | InnoDB | Otimização
## Comandos Rápidos
```bash
mysql -h localhost -u root -p mydb
mysql -h host -u user -p -e "SELECT NOW();" mydb
mysql -h host -u user -p mydb < migration.sql
```
## Schema Design
```sql
CREATE TABLE users (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
> **SEMPRE** `ENGINE=InnoDB` — transações, FK, row-level locking. `utf8mb4` — suporta emoji e acentos completos.
## JSON Ops
```sql
CREATE TABLE orders (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
metadata JSON,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
SELECT * FROM orders WHERE JSON_EXTRACT(metadata, '$.source') = 'web';
-- Shorthand (MySQL 8+):
SELECT * FROM orders WHERE metadata->>'$.source' = 'web';
```
## Indexes
```sql
-- Index composto
CREATE INDEX idx_orders_user_id ON orders(user_id);
-- Índice parcial (simulado com generated column + índice)
ALTER TABLE orders ADD COLUMN is_active TINYINT(1)
GENERATED ALWAYS AS (status != 'cancelled') STORED;
CREATE INDEX idx_orders_active ON orders(is_active);
```
## Joins e Agregações
```sql
SELECT u.name, o.total, o.status
FROM users u
INNER JOIN orders o ON o.user_id = u.id
WHERE o.created_at > '2026-01-01'
ORDER BY o.total DESC
LIMIT 10;
SELECT status, COUNT(*) AS cnt, SUM(total) AS revenue
FROM orders GROUP BY status HAVING cnt > 5;
```
## Diferenças principais vs PostgreSQL
| Aspecto | MySQL | PostgreSQL |
|---------|-------|-------------|
| Auto-increment | `AUTO_INCREMENT` | `SERIAL` / `IDENTITY` |
| UUID padrão | Requer plugin (não padrão) | `uuid-ossp` built-in |
| JSON | `JSON` type (baixa performance em queries) | `JSONB` indexável |
| CTEs | Suportado (MySQL 8+) | Nativo desde sempre |
| Window Functions | MySQL 8+ | Nativo |
| Transactions | InnoDB obrigatório | Sempre |
| Null-safe join | `<=>` (spaceship operator) | `IS NOT DISTINCT FROM` |
+99
View File
@@ -0,0 +1,99 @@
# PostgreSQL — Patterns e Anti-patterns
> Conexão | Schemas | JSONB | Junções | Window Functions | Migrações | EXPLAIN
## Comandos Rápidos
```bash
psql "postgresql://user:pass@host:5432/db?sslmode=require"
psql -h localhost -U user -d db -c "SELECT NOW();"
psql -h host -U user -d db -f migration.sql
```
## Schema Design
```sql
-- UUIDs para PK distribuído-friendly (ativar extensão primeiro)
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'user' CHECK(role IN ('user','admin','moderator')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Auto-update updated_at
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql;
CREATE TRIGGER update_users_modtime BEFORE UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION update_modified_column();
-- Enum
CREATE TYPE order_status AS ENUM ('pending','paid','shipped','cancelled');
```
## JSONB Ops
```sql
INSERT INTO orders (metadata) VALUES ('{"source":"web","items":[{"sku":"A1","qty":2}]}'::jsonb);
SELECT * FROM orders WHERE metadata->>'source' = 'web';
SELECT * FROM orders WHERE metadata->'items' @> '[{"sku":"A1"}]'::jsonb; -- @> contains
UPDATE orders SET metadata = jsonb_set(metadata, '{source}', '"mobile"') WHERE id = '...';
SELECT metadata->>'coupon' AS coupon, COUNT(*) FROM orders GROUP BY 1;
```
## Indexes
```sql
CREATE UNIQUE INDEX idx_users_email ON users(email); -- único
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at); -- composto
CREATE INDEX idx_orders_active ON orders(user_id, created_at) -- parcial
WHERE status NOT IN ('delivered','cancelled');
CREATE INDEX idx_orders_metadata ON orders USING GIN(metadata); -- GIN para JSONB
```
## Window Functions
```sql
SELECT date, revenue,
SUM(revenue) OVER (ORDER BY date) AS cumulative_revenue, -- running total
AVG(revenue) OVER (PARTITION BY region) AS avg_by_region,
RANK() OVER (ORDER BY revenue DESC) AS ranking
FROM daily_sales;
```
## JOINS Rápidos
```sql
-- LEFT JOIN pega todos os usuários, mesmo sem pedidos
SELECT u.name, COUNT(o.id) AS order_count, COALESCE(SUM(o.total), 0) AS total_spent
FROM users u LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.name HAVING COUNT(o.id) > 5 ORDER BY total_spent DESC;
```
## CTEs (WITH)
```sql
WITH active_users AS (
SELECT id, name FROM users WHERE active = true
)
SELECT au.name, COUNT(o.id) AS orders
FROM active_users au LEFT JOIN orders o ON o.user_id = au.id
GROUP BY au.name;
```
## EXPLAIN ANALYZE (antes de otimizar)
```bash
EXPLAIN ANALYZE SELECT ... -- SEMPRE antes de criar um índice
```
## Migrations — Padrão
```bash
# Criar timestamped
psql -h host -U user -d db -f migrations/2025-06-19_add_field.sql
```
## Checklist de Otimização
- [ ] `EXPLAIN ANALYZE` antes e depois de cada mudança
- [ ] Medir tempo de resposta alvo antes de otimizar
- [ ] Evitar `SELECT *` em produção
- [ ] Criar índices para colunas em `WHERE`, `JOIN`, `ORDER BY`
- [ ] Índice parcial para subconjuntos pequenos
- [ ] Partial/Paginado para tabelas grandes
+64
View File
@@ -0,0 +1,64 @@
# Docker — Multi-Stack Deploy
> Extraído de `xcloud-docker-deploy` v1.2.1 + habilidades de openclaw-power-ops
## 🗺️ Stack Detection Router
| Arquivo encontrado | Stack | Ação |
|-------------------|-------|------|
| `wp-config.php` ou `wp-content/` | WordPress | Ver ref `xcloud-native-wordpress.md` |
| `composer.json` + `artisan` | Laravel | Ver ref `xcloud-native-laravel.md` |
| `package.json` + `next.config.*` | Next.js | Usar `dockerfiles/nextjs.Dockerfile` |
| `package.json` | Node.js | Ver ref `xcloud-native-nodejs.md` |
| `composer.json` (sem artisan) | PHP | Ver ref `xcloud-native-php.md` |
| `requirements.txt` ou `pyproject.toml` | Python | Usar `dockerfiles/python-fastapi.Dockerfile` |
| `go.mod` | Go | Gerar Dockerfile manualmente |
| `docker-compose.yml` existe | Docker existente | Prosseguir Step 1 |
## Step 1 — Cenário Detection
| Sinal | Cenário |
|-------|---------|
| `build:` ou `context: .` | **A** — Build-from-source |
| Caddy/Traefik/nginx-proxy | **B** — Proxy conflict |
| Múltiplos `ports:` por service | **B** — Multi-port |
| `./nginx.conf` volume mount | **B** — External config |
| Múltiplos services com `build:` | **C** — Multi-service build |
| `image: public-image`, 1 porta | ✅ Já compatível |
## Cenário A — Build-from-Source
1. Remover `build:` do compose
2. Trocar `image:` por `ghcr.io/OWNER/REPO:latest`
3. Gerar `.github/workflows/docker-build.yml`
4. Gerar `.env.example`
## Cenário B — Proxy Conflict
1. Remover Caddy/Traefik/nginx-proxy service
2. Remover SSL labels e multi-port — usar `expose:` (interno)
3. Adicionar `nginx-router` service com `configs:` inline
4. Expor uma porta (default: 3080)
## Cenário C — Multi-Service Build
- Matrix GitHub Actions — cada service com `build:` vira um GHCR image
- Compose atualizado com todas as imagens GHCR
## 🚨 Regras de Ouro (xCloud)
- ❌ Nunca incluir `build:` no compose final — xCloud ignora silenciosamente
- ❌ Nunca expor portas de DB diretas (`5432:5432`) — usar `expose:`
- ❌ Nunca incluir Caddy, Traefik, nginx-proxy, Let's Encrypt
- ✅ Preservar `environment:`, `volumes:`, `healthcheck:`
- ✅ Sempre usar `expose:` (interno), não `ports:` (para serviços internos)
## Dockerfiles Disponíveis
| Stack | Dockerfile |
|-------|------------|
| PHP genérico | `dockerfiles/php-generic.Dockerfile` |
| Laravel | `dockerfiles/laravel.Dockerfile` |
| Node.js | `dockerfiles/node-app.Dockerfile` |
| Next.js | `dockerfiles/nextjs.Dockerfile` |
| Python FastAPI | `dockerfiles/python-fastapi.Dockerfile` |
## Compose Templates
- `compose-templates/laravel-mysql.yml`
- `compose-templates/nextjs-postgres.yml`
- `compose-templates/nodejs-api-postgres.yml`
- `compose-templates/python-fastapi-postgres.yml`
+50
View File
@@ -0,0 +1,50 @@
# OpenClaw — Gateway Ops CLI
> Referência rápida baseada em `openclaw-power-ops` + `openclaw-config`.
## 🌟 Golden Rules
1. ❌ NUNCA editar `openclaw.json` diretamente — sempre `openclaw config set/get/unset`
2. ✅ Sempre reiniciar gateway após mudanças de config
3. ❌ Telegram: NÃO usar campo `agent` dentro de config de conta — usar `bindings` array
4. ❌ Telegram `streaming`: deve ser string `"off"`, não booleano `false`
5. ✅ JSON values em `config set` precisam de `--strict-json`
## Diagnóstico
```bash
openclaw status # overview
openclaw status --deep # detalhado
openclaw doctor # encontra problemas
openclaw doctor --fix # auto-fix (com consentimento do usuário!)
openclaw gateway health # health check do gateway
openclaw security audit # scan de segurança
openclaw security audit --deep --fix # scan profundo + auto-fix
```
## Config Segura — $include Modular
```json5
// ~/.openclaw/openclaw.json
{
"$include": ["./gateway.json5", "./channels/telegram.json5"],
}
```
- `$include`: resolved antes da validação de schema
- Objetos: merge recursivo; Arrays: concatenam; Primitivos: último vence
- Limite: profundidade máx 10; includes circulares são detectados
## Telegram — Exemplos
```bash
# DM policy open (cuidado!)
openclaw config set channels.telegram.dmPolicy '"open"' --json
openclaw config set channels.telegram.allowFrom '["*"]' --json
# Streaming OFF (string, não boolean)
openclaw config set channels.telegram.streaming '"off"' --json
```
## Enabling Features
```bash
# Web search (Brave/Perplexity)
openclaw config set tools.web.search.enabled true --json
openclaw config set tools.web.search.provider '"brave"' --json
# Chave via env var: export BRAVE_API_KEY="***"
```
+134
View File
@@ -0,0 +1,134 @@
# System Diagnostic — Linux Cheatsheet
> Comandos essenciais para análise de sistema, processos, disco, rede e segurança.
## Diagnóstico Rápido
```bash
uptime # Uptime + média de carga (1, 5, 15 min)
w # Usuários logados + carga
dmesg -T # Logs do kernel com timestamp
who # Quem está logado agora
last # Histórico de login
lastlog # Último login de cada usuário
lsb_release -a # Versão do SO
uname -a # Kernel info completo
lscpu # Info da CPU
lsblk # Dispositivos de bloco (discos)
mount | column -t # Filesystems montados
df -h # Uso de disco (human-readable)
df -i # Inodes por filesystem
free -h # RAM/Swap
swapon --show # Partições de swap ativas
cat /proc/loadavg # Load average preciso
```
## 🔍 Saúde do Sistema
```bash
# Processos por CPU
ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head
# Top em tempo real
htop
top
# Serviços com problema
systemctl --type=service --state=failed
systemctl list-units --state=failed
# Atualizações disponíveis
apt list --upgradable 2>/dev/null | grep "^.*/.*"
dnf check-update 2>/dev/null
```
## 🕵️ Análise de Logs
```bash
# Logs de системы em tempo real
journalctl -f
journalctl -u nginx --since "1h"
journalctl -p err --since "30min" # Apenas erros recentes
# Logs de autenticação
grep "Failed password" /var/log/auth.log
grep "Accepted" /var/log/auth.log | tail -20
# Logs estruturados (JSON) com jq
jq 'select(.level=="ERROR") | .user + ": " + .message' app.log
# Tamanho de arquivos de log
du -sh /var/log/
find /var/log -name "*.log" -size +100M -exec ls -lh {} \;
# Erros em tempo real
tail -f /var/log/syslog
```
## 🕸️ Diagnóstico de Rede
```bash
ss -tlnp # Portas TCP abertas (listening) — substitui netstat
ss -tunp # Todas as conexões (TCP/UDP)
ss -s # Estatísticas de conexão
ip addr # Endereços IP das interfaces
ip route # Tabela de roteamento
ping -c 5 8.8.8.8 # Teste de conectividade
traceroute 8.8.8.8 # Rota até destino
mtr --report 8.8.8.8 # Traceroute + estatísticas contínuas
nslookup dominio.com # DNS lookup
dig dominio.com A # DNS detalhado
# Velocidade de download
curl -o /dev/null -s -w 'Speed: %{speed_download} bytes/sec\n' http://example.com/file
# WHOIS
whois dominio.com
curl -s https://ipinfo.io/json
```
## 🔐 Usuários e Permissões
```bash
who # Quem está logado
w # Mais detalhes (idle, processo)
id # UID/GID do usuário atual
sudo -l -U root # O que root pode executar sem senha
grep sudo /etc/group # Quem está no grupo sudo
# Ou: lista de usuários com UID >= 1000
awk -F: '($3 >= 1000) && ($3 < 65534)' /etc/passwd
# Permissões de arquivo
find /pasta -perm /111 -ls # Todos os executáveis na pasta
namei -l /caminho/para/arquivo # Mostra permissões em cada nível
stat /caminho/arquivo # Permissões detalhadas + dono + timestamps
# SSH
sshd -T # Configuração SSH ativa (efetiva)
ssh-copy-id user@host # Copiar chave pública para remoto
```
## 💻 Scripts Shell
```bash
#!/usr/bin/env bash
set -euo pipefail # Erro se: erro (-e), variável não definida (-u), pipe falha (-o pipefail)
# Logging
log() {
echo "[$(date -Iseconds)] $*" >> /var/log/meu-script.log
}
log "Iniciando..."
# Trap para cleanup — executa no EXIT ou SIGINT
trap 'rm -f /tmp/$$tmpfile; log "Limpeza concluída"' EXIT
# Verificar binário antes de usar
if ! command -v jq >/dev/null 2>&1; then
log "ERRO: jq não encontrado"
exit 1
fi
```
## 📦 Monitoramento de Saúde
```bash
# Verificar Uptime de um processo
systemd-analyze time
systemd-analyze critical-chain
# Histórico de uso de CPU/memória por processo
pidstat -u -p ALL 1 5
# Memória detalhada
cat /proc/meminfo | grep -E "MemTotal|MemAvailable|MemFree"
```
+103
View File
@@ -0,0 +1,103 @@
# Next.js — Best Practices
> Extraído de skills: `next-best-practices` v0.1.0 + `nextjs-patterns` v1.0.0
## 🏗️ Estrutura de Projeto (App Router)
```
app/
├── (marketing)/ # Route group — não aparece na URL
│ └── page.tsx
├── (dashboard)/
│ ├── layout.tsx # Layout compartilhado do grupo
│ ├── [id]/
│ │ └── page.tsx # Página dinâmica
│ └── loading.tsx # Suspense boundary automático
├── api/
│ └── route.ts # Route Handler (REST/GraphQL)
├── error.tsx # Error boundary por rota
├── not-found.tsx # Página 404
└── layout.tsx # Root layout (obrigatório)
```
## 🖥️ Server vs Client Components
```tsx
// ✅ Server Component (padrão) — roda no servidor, nenhum JS no cliente
async function ProductList() {
// DB query acontece no servidor!
const products = await db.product.findMany();
return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
}
// ✅ Client Component — só quando precisar de interatividade
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(n => n + 1)}>{count}</button>;
}
// ✅ Server Actions — mutations sem criar API routes
async function createProduct(formData: FormData) {
"use server";
await db.product.create({ data: { ... } });
}
```
## 📊 Padrões de Data Fetching
| Padrão | Quando usar | Exemplo |
|--------|-------------|---------|
| **Server Component `await`** | Read, página ou componente | `const posts = await db.post.findMany()` |
| **Server Actions** | Write/mutations, formulários | `"use server"` + `revalidatePath` |
| **Route Handlers** | REST/GraphQL API, webhooks, integrações | `app/api/users/route.ts` |
| **`use()` hook** | Ler promise em Client Components | `const data = use(fetchData())` |
### Evitando Data Waterfalls
```tsx
// ❌ Ruim — sequencial, cada await aguarda o anterior
async function Page() {
const user = await getUser(); // 200ms
const posts = await getPosts(); // 300ms (só começa após user)
return <Profile user={user} posts={posts} />;
}
// ✅ Bom — paralelo
async function Page() {
const [user, posts] = await Promise.all([
getUser(), // começa imediatamente
getPosts(), // começa imediatamente
]);
return <Profile user={user} posts={posts} />;
}
```
## 🗄️ Database Client Singleton
```ts
// lib/db.ts — criar uma vez por request (Server Component boundary)
import { PrismaClient } from '@prisma/client';
const globalForDb = globalThis as unknown as { prisma: PrismaClient };
export const db = globalForDb.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalForDb.prisma = db;
```
## 🔄 Caching — 4 Camadas Next.js
| Camada | O que cacheia | Controlado por |
|--------|---------------|----------------|
| **Request Memoization** | `fetch`, `React.cache()` | automático por request |
| **Data Cache** | `fetch` responses | `next: { revalidate: 60 }` |
| **Full Route Cache** | Render completo | `export const revalidate` |
| **Router Cache** | Estado do cliente após navegação | `next/router` |
```ts
// Revalidar após 60s
fetch(url, { next: { revalidate: 60 } });
// Não cachear (sempre fresh)
fetch(url, { next: { revalidate: 0 } });
```
## ⚠️ Regra Fundamental
> **`"use client"` é uma barreira de escape.** Tudo dentro de um arquivo com essa diretiva
> roda no navegador. Tudo SEM ela roda no servidor. Quando possível, fique no servidor.
+62
View File
@@ -0,0 +1,62 @@
# SAST — Security Audit Guide
> Use APENAS quando o usuário explicitamente pedir análise de segurança.
## Severidade
| Nível | Impacto |
|-------|---------|
| Critical | RCE, exfiltração de dados, instruction override |
| High | Leitura/modificação de dados sensíveis, bypass de ACL |
| Medium | Dados limitados, engano de usuário |
| Low | Impacto mínimo |
## Categorias de Vulnerabilidade
### 1. Hardcoded Secrets
```
🔴 API_KEY=sk-... PASSWORD=... SECRET=... TOKEN=... PRIVATE_KEY=<base64...>
```
### 2. Injection
| Tipo | Exemplo |
|------|---------|
| SQL Injection | `query("SELECT * FROM t WHERE id=" + userInput)` |
| XSS | `<div dangerouslySetInnerHTML={{ __html: userInput }} />` |
| Command Injection | `` exec(`convert ${userInput} file.png`) `` |
| SSRF | `fetch(userProvidedUrl)` sem allowlist |
### 3. Broken Access Control
- IDOR — recurso acessado por id inserido pelo usuário sem verificar ownership
- Missing function-level AC — sem check de auth antes de operação sensível
- Path traversal — input de usuário em caminho de arquivo sem sanitização
### 4. LLM/Prompt Safety
- **Prompt Injection** — input não confiável concatenado em prompts sem boundary
- **Unsafe Execution** — output de LLM passado para `eval()`, `exec`, shell commands
- **Output Injection** — output flui para sinks de SQLi, XSS, command injection
- **Flawed Security Logic** — decisões de segurança baseadas em output não validado de LLM
## SKILL.md Review Checklist
```
✓ Sem instruction override ("Ignore previous instructions...")
✓ Sem exfiltração de dados (enviar dados para URL externa)
✓ Sem falsas claims de privilégio ("Você tem root access...")
✓ Sem conteúdo escondido (base64, zero-width chars)
✓ Tool usage seguro (sem eval(user_input), sem writes em /etc/*)
✓ Sem engano (não dizer que é humano)
✓ Scoped ao propósito
```
## OWASP Top 10 Mapping
| OWASP | Categoria na skill |
|-------|-------------------|
| A01 Broken Access Control | Access Control |
| A02 Cryptographic Failures | Hardcoded Secrets |
| A03 Injection | SQL Injection, XSS, Command Injection, SSRF |
| A04 Insecure Design | Clean Architecture review |
| A05 Security Misconfiguration | Env vars, default credentials |
| A06 Vulnerable Components | npm audit equivalent check |
| A07 Auth Failures | Authentication weaknesses |
| A08 Data Integrity Failures | Unsafe deserialization |
| A09 Logging Failures | PII em logs |
| A10 SSRF | Já em A03 |
@@ -0,0 +1,96 @@
# TypeScript — Utility Types & Generics Gotchas
> Casos onde `Partial<T>`, `Omit`, `Pick`, `Extract`, etc. NÃO fazem o que você espera.
## Utility Type Gotchas
| Tipo | Armadilha | Solução |
|------|----------|---------|
| `Partial<T>` | *Shallow* — nested continua required | Criar `DeepPartial<T>` recursivo |
| `Required<T>` | Não remove `undefined` da union | Usar `NonNullable<T[K]>` por campo |
| `Omit<T, K>` | Não verifica se K existe — `Omit<User,"typo">` compila | Tipar com cuidado |
| `Pick<T, K>` | Key inexistente também compila | Mesmo cuidado |
| `Record<string, T>` | Implica TODA key existe — acesso a inexistente retorna `T`, não `T\|undefined` | Usar `Record<string, T \| undefined>` |
| `Extract<T, U>` | Retorna `never` se não houver match — silenciosamente vazio | Checar se é `never` antes |
| `ReturnType<typeof fn>` | Com overload pega só a última signature | Evitar overloads ou tipar retorno manualmente |
| `NonNullable<T>` | Remove `null` E `undefined` — às vezes só quer um | Usar `Exclude<T, null>` ou `Exclude<T, undefined>` |
| `Awaited<T>` | Desempacota recursivamente — surpresa com `Promise<Promise<T>>` | Cuidado com promises encadeadas |
## Generics — Armadilhas Práticas
```ts
// ❌ <T = any> foge do any para todo o código
function parse<T = any>(raw: string): T { ... }
// ✅ Deixe o caller fornecer o tipo, ou use unknown
function parse<T>(raw: string): T { ... }
// ou
function parse(raw: string): unknown { ... }
// ❌ <T extends object> permite arrays
function merge<T extends object>(a: T, b: T): T { ... }
merge([1, 2], [3, 4]) // compila, mas não deve
// ✅ Use Record<string, unknown> para objetos puros
function merge<T extends Record<string, unknown>>(a: T, b: T): T { ... }
// ❌ <T extends string> com literal infere string, não o literal
function prefix<T extends string>(p: T) { ... }
prefix("http") // T é "http", não "http" literal nesse contexto
// ✅ Use const assertion para preservar literais
const urls = ["/api", "/auth"] as const; // readonly ["/api", "/auth"]
```
## `keyof` em Função Genérica
```ts
// ❌ keyof T em função genérica é sempre string | number | symbol
function getProp<T, K extends keyof T>(obj: T, key: K) { ... }
// ✅ Para objeto puro, restringir:
function getProp<T extends Record<string, unknown>, K extends keyof T>(
obj: T, key: K
): T[K] {
return obj[key];
}
```
## Covariância e Contravariância
```ts
// ❌ Arrays são COVARIANTES — Dog[] atribuível a Animal[] mas push(Cat) quebra runtime
const dogs: Dog[] = [];
const animals: Animal[] = dogs; // ✅ compila
animals.push(new Cat()); // 🚨 runtime error
// ❌ Parâmetros de função são CONTRAVARIANTES
type Handler = (animal: Animal) => void;
const dogHandler: Handler = (dog: Dog) => { ... }; // ❌ não compila
// (Animal) espera receber Animal, não só Dog
```
## Mapped Types — Preservando Modificadores
```ts
// ❌ { [K in keyof T]: T[K] } — PERDE readonly e optional
type StrictClone<T> = { [K in keyof T]: T[K] };
// → { readonly name: string } vira { name: string }
// ✅ Preservar modificadores com -readonly, -?
type Preserve<T> = { -readonly [K in keyof T]: T[K] };
type Optionalize<T> = { -? [K in keyof T]: T[K] };
```
## Conditional Types — Distributividade
```ts
// ✅ Distribui sobre union
type NonNullableValues<T> = T extends null | undefined ? never : T;
type Result = NonNullableValues<string | null | number | undefined>;
// Result = string | number ← distribuiu corretamente
// ❌ Para não distribuir, usar [T] (tupla wrapper)
type WrapNonNullable<T> = [T] extends [null | undefined] ? never : T;
// Não distribui — útil quando a distribuição causa comportamento inesperado
```
@@ -0,0 +1,76 @@
# TypeScript — Safe Patterns
> Extraído de skills: typescript v1.0.2, generics.md, utility-types.md, declarations.md
## Anti-pattern: Evite `any`
- Use `unknown` quando não souber o tipo — força narrowing antes do uso
- Respostas de API: tipar ou `unknown`, nunca `any`
## Narrowing Failures
| Padrão | Problema | Solução |
|--------|---------|---------|
| `filter(Boolean)` | Não narrovia | `.filter((x): x is T => Boolean(x))` |
| `Object.keys(obj)` | Retorna `string[]` | Usar `keyof typeof obj` é intencional — objetos podem ter chaves extras |
| `Array.isArray()` | Narrovia para `any[]` | Pode precisar assertion de tipo de elemento |
| `useState<User>()` | Infere `User \| undefined` | Tratar undefined inicial |
| `Promise.all([a(), b()])` | Infere tupla só com `as const` | Usar `as const` na array |
## Literal Type Traps
- `let x = "hello"``string`. Use `const` ou `as const` para literal
- Propriedades de objeto alargam: `{ status: "ok" }``status: string`
- Retorno de função alarga — anote explicitamente para retornos literais
## `satisfies` vs Type Annotation
```ts
// ❌ Perde info literal
const config: RouteConfig = { path: "/home", method: "GET" };
// ✅ Mantém literal + valida compatibilidade
const config = { path: "/home", method: "GET" } satisfies RouteConfig;
```
> Preferir `satisfies` para config objects.
## Strict Null Handling
- `?.` retorna `undefined`, não `null`
- `??` captura só `null`/`undefined`; `||` captura tudo falsy (`0`, `""`, `false`)
- `!` (non-null assertion) — último recurso; preferir narrowing ou early return
## Generics — Armadilhas Comuns
- `<T = any>` foge do `any` — restringe todo o código
- `<T extends object>` permite arrays — usar `Record<string, unknown>` para objetos puros
- Arrays são covariantes — `Dog[]` atribuível a `Animal[]` mas `push(Cat)` quebra em runtime
- Parâmetros de função são contravariantes — `(Animal) => void` NÃO é atribuível a `(Dog) => void`
- `Partial<T>` e `Required<T>` são *shallow* — não afetam nested:
```ts
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};
```
## Discriminated Unions
```ts
type Result<T> =
| { ok: true; data: T }
| { ok: false; error: string };
function handle(r: Result<User>) {
if (r.ok) {
console.log(r.data.name); // ✅ T automaticamente
} else {
console.log(r.error); // ✅ narrowed
}
}
```
- Switch exaustivo: `default: const _never: never = x` → erro de compilação se caso faltar
## Module Boundaries
- `import type` — stripped em runtime, evita problemas de bundler
- Re-export types: `export type { X }` — previne dependência runtime acidental
- `.d.ts` augmentation: usar `declare module` com path exato do módulo
## Declaration File Gotchas
- `declare module "x"` precisa de path EXATO — `"lodash"``"lodash/index"`
- `interface` pode ser mergeado de outros arquivos — `type` não pode
- Export default em `.d.ts` é problemático — preferir named exports
+110
View File
@@ -0,0 +1,110 @@
# Vue 3 — Composition API Best Practices
> Extraído de skills: `vue` + `vue-composition-api-best-practices`
## `<script setup>` Padrão Ouro
```vue
<script setup lang="ts">
// ✅ Importações no topo — tree-shakeable
import { ref, computed, onMounted } from 'vue'
import { useUserStore } from '@/stores/user'
// ✅ Composables começam com `use`
const user = useUserStore()
const selectedId = ref<number | null>(null)
// ✅ Estado + getters no mesmo lugar
const filteredUsers = computed(() =>
user.list.filter(u => u.active)
)
// ✅ Lifecycle no fim
onMounted(() => user.fetchAll())
</script>
<template>
<button v-if="filteredUsers.length > 0" @click="selectedId = null">
Clear
</button>
</template>
```
## Composables — `useXxx` Pattern
```ts
// composables/usePagination.ts
export function usePagination<T>(items: T[], pageSize = 20) {
const page = ref(1)
const totalPages = computed(() => Math.ceil(items.value.length / pageSize))
const paginated = computed(() =>
items.value.slice((page.value - 1) * pageSize, page.value * pageSize)
)
return { page, totalPages, paginated }
}
```
## <script setup> Deep Dive
```vue
<!-- BOM validade automática, minificado -->
<script setup lang="ts">
defineProps<{ msg: string }>()
const emit = defineEmits<{ (e: 'update', id: number): void }>()
</script>
<!-- RUIM option API misturado -->
<script lang="ts">
export default {
data() { return { x: 1 } },
methods: { /* ... */ }
}
</script>
```
## State Management — Pinia
```ts
// stores/counter.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() { count.value++ }
return { count, double, increment }
})
```
## Reactividade — Principais Armadilhas
- `ref` vs `reactive`: use `ref` por padrão (tipagem simples); `reactive` para objetos grandes
- Perda de reatividade ao desestruturar — usar `toRefs()` ou `storeToRefs()`
- `watch` vs `watchEffect`: `watch` é mais controlado; `watchEffect` é automático mas menos previsível
- `v-if` vs `v-show`: `v-if` remove do DOM; `v-show` togglea `display`
## Type-Safe Vue
```vue
<script setup lang="ts">
// Props tipadas — importa de arquivo separado se for reutilizável
const props = defineProps<{
userId: number
items: Item[]
requiredValue: string
}>()
const emit = defineEmits<{
(e: 'delete', id: number): void
(e: 'save', data: FormData): void
}>()
</script>
```
## Vue Router Traps
- `useRoute()` para rota atual — reativa, usar em setup
- `useRouter()` para navegação — `router.push('/path')`
- Guards: `beforeEach`, `beforeResolve`, `afterEach` — retornar `false` cancela
- `<RouterView>` com named views — múltiplas views por rota
## Common Mistakes
- `key` em `v-for` é obrigatório — `v-for="item in items" :key="item.id"`
- Ordem de event modifiers importa — `.prevent.stop``.stop.prevent`
- `Teleport` para modais — `<Teleport to="body">` renderiza fora da árvore