Files
pulse-memory/.learnings/LEARNINGS.md
T

6.4 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

[LRN-20260520-001] vitest-pure-dom-matchers

Logged: 2026-05-20T00:52:00-03:00 Priority: high Status: applied Area: testing

Summary

Vitest jsdom puro — matchers nativos DOM valem mais que @testing-library/jest-dom para projetos pequenos

Details

Problema: @testing-library/jest-dom não estava instalado. Erros "Invalid Chai property: toHaveClass" apareceram em 44 testes.

Solução aplicada: trocar todos os 56 testes de componentes para usar:

  • .classList.contains('bg-indigo-600') ao invés de .toHaveClass('bg-indigo-600')
  • .getAttribute('id') ao invés de .toHaveAttribute('id', 'x')
  • .textContent / container.querySelector() ao invés de `screen.getByText()
  • tagName ao invés de getByRole('heading')

Resultado: 56/56 testes verdes, 0 dependências extras.

Suggested Action

Padronizar esta abordagem em todos os arquivos de teste. Só instalar @testing-library/jest-dom se surgir matcher que não dá para escrever com .classList.contains() nativo.

Metadata

  • Source: best_practice
  • Tags: vitest, jsdom, testing, dom, pure-matchers
  • Pattern-Key: vitest.pure-dom-matchers
  • Recurrence-Count: 1

[LRN-20260520-002] jsdom-fireEvent-writable-value

Logged: 2026-05-20T00:52:00-03:00 Priority: low Status: workaround Area: testing

Summary

No jsdom, value de <input> não é writable — fireEvent.change não atualiza input.value diretamente

Details

Worksaround: Object.defineProperty(inp, 'value', { writable: true, value: 'abc' }) antes de fireEvent.change(inp). Confirmado como solução mínima para testes de onChange em estruturas Tree AST plantes como jsdom.

Suggested Action

Criar helper test-utils.ts com setInputValue(el, val) para encapsular o workaround.

Metadata

  • Source: error
  • Tags: jsdom, fireEvent, input, value, onChange
  • Pattern-Key: jsdom.fireEvent-change-writable
  • Recurrence-Count: 1