Files
pulse-libs/.learnings/LEARNINGS.md
T
pulse-agent 9afdccdc14 feat(tests-hooks): 23/23 hooks tests pass — useToggle, useAsync, useDebounce, useLocalStorage, useMedia, useInterval, useClipboard, useFetch
- useLocalStorage: retorna tupla [valor, setter] tipada como [T, (v: T|fn) => void]
- useAsync: espera microtask act cycle antes de checar status
- useClipboard: mock navigator.clipboard.writeText antes
- useMedia: mock matchMedia antes
- Busca por padrão: act() + waitFor p/ efeitos assíncronos (sem fakeTimers gerais)
- docs: PROJECTS-REGISTER, SESSION-STATE (pretérito + presente)
2026-05-19 23:37:04 -03:00

4.5 KiB

Learnings — Padrões bem-sucedidos

Registro de padrões que funcionam, para replicar.


[LRN-20260519-001] category

Logged: 2026-05-19T20:39:00-03:00 Priority: high Status: pending Area: config

Summary

Instalar skills do Clawhub com /var/lib/openclaw/tools/node/npm/bin/clawhub

Details

O CLI clawhub não está no $PATH global, mas existe instalado em /var/lib/openclaw/tools/node/npm/bin/clawhub. Sempre usar o caminho completo.

Suggested Action

Adicionar symlink ou alias para clawhub no PATH do agente, ou sempre usar o caminho completo.

Metadata

  • Source: error
  • Tags: clawhub, cli, path, install
  • Pattern-Key: clawhub.cli_path

[LRN-20260519-002] clawhub-search-qc

Logged: 2026-05-19T20:42:00-03:00 Priority: medium Status: pending Area: config

Summary

clawhub search com termos muito específicos retorna vazio; usar termos genéricos primeiro

Details

Pesquisas com termos combinados como "programming developer full-stack" retornaram vazio. Termos simples como "autonomous agent" retornaram resultados. Melhor abordar a pesquisa em múltiplas queries curtas.

Suggested Action

Fazer múltiplas searches com termos curtos e depois filtrar manualmente.

Metadata

  • Source: error
  • Tags: clawhub, search, query
  • Pattern-Key: clawhub.search_strategy

[LRN-20260519-003] biblioteca-compartilhada-libs

Logged: 2026-05-19T21:30:00-03:00 Priority: medium Status: pending Area: config

Summary

Criar biblioteca inteligente compartilhada em libs/ para reuso entre projetos, com conhecimento extraído de todas as skills instaladas.

Details

Toda skill que instalamos tem conhecimento valioso (padrões, gotchas, templates). Ao invés de cada agente lembrar de cor, centralize em libs/<dominio>/:

  • skills são extraídas e promovidas para arquivos .md limpos na biblioteca
  • novos projetos copiam libs/ como template de padrões
  • o próprio agente consulte libs/ antes de implementar qualquer coisa

Suggested Action

Quando instalar nova skill:

  1. Ler o SKILL.md
  2. Extrair o conhecimento útil
  3. Promover para libs/<dominio>/ apropriado
  4. Atualizar libs/INDEX.md

Metadata

  • Source: best_practice
  • Tags: biblioteca, reuso, padroes, compartilhamento
  • Pattern-Key: libs.shared_knowledge_base
  • Recurrence-Count: 1


[LRN-20260519-004] category

Logged: 2026-05-19T23:10:00-03:00 Priority: high Status: pending Area: testing

Summary

Vitest jsdom — mocks obrigatórios antes de renderizar hooks que usam APIs do navegador

Details

No ambiente jsdom:

  • localStorage não existe → mock com Object.defineProperty(global, 'localStorage', ...) antes de qualquer hook useLocalStorage
  • navigator.clipboard não existe → mock antes de useClipboard
  • window.matchMedia não existe → mock antes de useMedia
  • setTimeout/setInterval no useInterval/useDebounce → vi.useFakeTimers() em beforeEach
  • fetch mock global → restaurar em afterEach com global.fetch = originalFetch

Suggested Action

Criar um arquivo tests/setup.ts com todos os mocks globais e importar em vitest.config.ts.

Metadata

  • Source: best_practice
  • Tags: vitest, jsdom, mocks, testing
  • Pattern-Key: vitest.jsdom.mocks
  • Recurrence-Count: 3

[LRN-20260519-005] category

Logged: 2026-05-19T23:10:00-03:00 Priority: medium Status: pending Area: testing

Summary

React Testing Library — renderHook + act() para testar hooks assíncronos

Details

Hooks que fazem async operations (useAsync, useFetch, useClipboard):

  1. renderHook retorna { result }
  2. Para atualizações async, sempre envolva em act(async () => { await ... })
  3. Para等待 promises: await act(async () => { await new Promise(r => setTimeout(r, ms)); })
  4. Com fakeTimers: act(() => { vi.advanceTimersByTime(ms); })
  5. Nunca acesse result.current diretamente após um await async — sempre dentro de act()

Suggested Action

Template de teste async:

it('descrição', async () => {
  global.fetch = vi.fn(() => Promise.resolve(makeRes(200, body))) as any;
  const { result } = renderHook(() => useFetch<T>('/url', {}));

  await act(async () => { await new Promise(r => setTimeout(r, 50)); });

  expect(result.current.status).toBe('success');
});

Metadata

  • Source: best_practice
  • Tags: react, testing-library, hooks, async, vitest
  • Pattern-Key: react.testing-library
  • Recurrence-Count: 3