<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged opencode</title>
<link>https://coderlegion.com/tag/opencode</link>
<description>Powered by Question2Answer</description>
<item>
<title>Migrando 177 sessões do OpenCode para o AI Memory: passo a passo com comandos</title>
<link>https://coderlegion.com/30982/migrando-177-sessoes-do-opencode-para-o-ai-memory-passo-a-passo-com-comandos</link>
<description>&lt;p&gt;&lt;strong&gt;Como importar o histórico de desenvolvimento para uma memória local&lt;br&gt;
pesquisável, validar os dados e organizar a migração no Debian.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;O histórico de uma ferramenta de desenvolvimento com IA pode acumular&lt;br&gt;
meses de decisões técnicas, diagnósticos, comandos e soluções. O desafio&lt;br&gt;
é tornar esse conhecimento reutilizável em novas sessões, sem depender&lt;br&gt;
de buscas manuais em conversas antigas.&lt;/p&gt;
&lt;p&gt;Neste artigo, compartilho o processo que utilizei para migrar sessões do&lt;br&gt;
OpenCode para o &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/akitaonrails/ai-memory&quot;&gt;AI Memory&lt;/a&gt;,&lt;br&gt;
incluindo preparação do ambiente, validação prévia, importação&lt;br&gt;
automatizada e conferência dos resultados.&lt;/p&gt;
&lt;h3 id=&quot;1-preparando-o-ambiente&quot;&gt;1. Preparando o ambiente&lt;/h3&gt;
&lt;p&gt;O ambiente utilizado foi Debian Linux, com OpenCode 2.0.28 e AI Memory&lt;br&gt;
2.6.5 durante a importação inicial. Posteriormente, atualizei o AI&lt;br&gt;
Memory para a versão 2.6.6 para corrigir um problema observado no&lt;br&gt;
comando &lt;code&gt;list-projects&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;O banco de dados original do OpenCode estava em:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;~/.local/share/opencode/opencode.db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Antes de iniciar, preservei o histórico original e mantive backups em&lt;br&gt;
&lt;code&gt;~/backups/opencode/&lt;/code&gt;. Para conferir os arquivos:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ls -lh ~/backups/opencode/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Importante:&lt;/strong&gt; não remova nem sobrescreva o banco original do OpenCode.&lt;br&gt;
A importação deve ocorrer para o armazenamento do AI Memory, mantendo&lt;br&gt;
uma cópia de segurança do histórico de origem.&lt;/p&gt;
&lt;h3 id=&quot;2-iniciando-e-validando-o-servidor&quot;&gt;2. Iniciando e validando o servidor&lt;/h3&gt;
&lt;p&gt;O AI Memory estava configurado para executar como serviço do usuário, na&lt;br&gt;
porta &lt;code&gt;49375&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl --user is-active ai-memory
systemctl --user status ai-memory --no-pager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Caso seja necessário reiniciá-lo:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl --user restart ai-memory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Defina a URL correta para o CLI:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export AI_MEMORY_SERVER_URL=http://127.0.0.1:49375
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para persistir a configuração no Bash:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;grep -qF 'export AI_MEMORY_SERVER_URL=http://127.0.0.1:49375' ~/.bashrc ||
  echo 'export AI_MEMORY_SERVER_URL=http://127.0.0.1:49375' &amp;gt;&amp;gt; ~/.bashrc

source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Essa variável é importante porque o CLI utilizava por padrão a porta&lt;br&gt;
&lt;code&gt;49374&lt;/code&gt;, enquanto o servidor estava escutando na &lt;code&gt;49375&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Valide a conexão:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ai-memory status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esse comando apresenta informações sobre o armazenamento, as sessões, as&lt;br&gt;
observações, a indexação textual e os embeddings.&lt;/p&gt;
&lt;h3 id=&quot;3-inventariando-e-validando-as-sess-es&quot;&gt;3. Inventariando e validando as sessões&lt;/h3&gt;
&lt;p&gt;O histórico estava distribuído entre vários projetos. Como o &lt;code&gt;backfill&lt;/code&gt;&lt;br&gt;
depende do diretório de trabalho para identificar o projeto e selecionar&lt;br&gt;
sessões, não bastava executar a importação a partir de qualquer pasta.&lt;/p&gt;
&lt;p&gt;Antes de importar, inventariei as sessões do banco original e executei&lt;br&gt;
uma simulação para identificar quais ainda tinham diretórios de projeto&lt;br&gt;
disponíveis.&lt;/p&gt;
&lt;h4 id=&quot;3-1-criar-o-script-de-valida-o&quot;&gt;3.1. Criar o script de validação&lt;/h4&gt;
&lt;p&gt;O script consulta o banco SQLite original do OpenCode, executa&lt;br&gt;
&lt;code&gt;ai-memory backfill&lt;/code&gt; em modo de simulação para cada sessão e registra o&lt;br&gt;
resultado em &lt;code&gt;~/backups/opencode/session-validation.log&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir -p ~/backups/opencode

cat &amp;gt; &quot;$HOME/backups/opencode/validate-sessions.sh&quot; &amp;lt;&amp;lt;'BASH'
#!/usr/bin/env bash
set -uo pipefail

DB=&quot;$HOME/.local/share/opencode/opencode.db&quot;
REPORT=&quot;$HOME/backups/opencode/session-validation.log&quot;

for cmd in sqlite3 jq ai-memory; do
  if ! command -v &quot;$cmd&quot; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
    echo &quot;ERRO: comando obrigatório não encontrado: $cmd&quot; &amp;gt;&amp;amp;2
    exit 1
  fi
done

if [[ ! -f &quot;$DB&quot; ]]; then
  echo &quot;ERRO: banco do OpenCode não encontrado: $DB&quot; &amp;gt;&amp;amp;2
  exit 1
fi

mkdir -p &quot;$(dirname &quot;$REPORT&quot;)&quot;
: &amp;gt; &quot;$REPORT&quot;

total=0
ok=0
missing=0
failed=0

printf 'Validação de sessões do OpenCode\n'
printf 'Banco: %s\n' &quot;$DB&quot;
printf 'Relatório: %s\n\n' &quot;$REPORT&quot;

while IFS=$'\t' read -r id directory; do
  [[ -n &quot;$id&quot; ]] || continue
  ((total += 1))

  if [[ -z &quot;$directory&quot; || ! -d &quot;$directory&quot; ]]; then
    printf 'MISSING\t%s\t%s\n' &quot;$id&quot; &quot;$directory&quot; | tee -a &quot;$REPORT&quot;
    ((missing += 1))
    continue
  fi

  output=&quot;$(
    cd &quot;$directory&quot; &amp;amp;&amp;amp;
      ai-memory backfill \
        --session &quot;$id&quot; \
        --max-sessions 1 \
        --dry-run \
        --json 2&amp;gt;&amp;amp;1
  )&quot;
  rc=$?

  if [[ $rc -eq 0 ]] &amp;amp;&amp;amp;
     jq -e '
       .selected == 1 and
       .failed_sessions == 0 and
       .dry_run == true
     ' &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;lt;&amp;lt;&amp;lt;&quot;$output&quot;; then
    printf 'OK\t%s\t%s\n' &quot;$id&quot; &quot;$directory&quot; | tee -a &quot;$REPORT&quot;
    ((ok += 1))
  else
    printf 'FAIL\t%s\t%s\n' &quot;$id&quot; &quot;$directory&quot; | tee -a &quot;$REPORT&quot;
    printf '%s\n' &quot;$output&quot; &amp;gt;&amp;gt; &quot;$REPORT&quot;
    printf '%s\n' '---' &amp;gt;&amp;gt; &quot;$REPORT&quot;
    ((failed += 1))
  fi
done &amp;lt; &amp;lt;(
  sqlite3 -separator $'\t' &quot;$DB&quot; \
    'SELECT id, directory
     FROM session_v2
     ORDER BY time_created, id;'
)

{
  printf '\nResumo da validação\n'
  printf 'Total: %d | OK: %d | MISSING: %d | Falhas: %d\n' \
    &quot;$total&quot; &quot;$ok&quot; &quot;$missing&quot; &quot;$failed&quot;
} | tee -a &quot;$REPORT&quot;

printf '\nRelatório salvo em: %s\n' &quot;$REPORT&quot;
BASH

chmod +x &quot;$HOME/backups/opencode/validate-sessions.sh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-2-executar-a-valida-o&quot;&gt;3.2. Executar a validação&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&quot;$HOME/backups/opencode/validate-sessions.sh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O script classifica cada sessão em três categorias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OK&lt;/code&gt;: diretório disponível e simulação do AI Memory concluída com o&lt;br&gt;
resultado esperado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MISSING&lt;/code&gt;: diretório original da sessão não existe mais.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FAIL&lt;/code&gt;: erro durante a simulação ou resultado diferente do esperado.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A validação usa &lt;code&gt;--dry-run&lt;/code&gt;, portanto não executa a importação efetiva&lt;br&gt;
das sessões.&lt;/p&gt;
&lt;h4 id=&quot;3-3-consultar-o-relat-rio&quot;&gt;3.3. Consultar o relatório&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cat ~/backups/opencode/session-validation.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para filtrar os registros e o resumo:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;grep -E '^(OK|MISSING|FAIL)|^Total:' \
  ~/backups/opencode/session-validation.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Na execução original, o inventário apresentou:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Total: 197 | OK: 177 | MISSING: 20 | Falhas: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As 177 sessões aprovadas foram consideradas aptas para a etapa seguinte.&lt;br&gt;
As 20 classificadas como &lt;code&gt;MISSING&lt;/code&gt; estavam associadas a diretórios de&lt;br&gt;
projetos que não estavam mais disponíveis.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Importante:&lt;/strong&gt; &lt;code&gt;OK&lt;/code&gt; indica que a sessão passou pela simulação, não que&lt;br&gt;
já foi importada. A importação efetiva deve ser executada&lt;br&gt;
posteriormente, após revisar o relatório e confirmar os projetos de&lt;br&gt;
origem.&lt;/p&gt;
&lt;p&gt;O relatório foi usado como entrada para automatizar a importação sem&lt;br&gt;
tentar processar as sessões excluídas.&lt;/p&gt;
&lt;h3 id=&quot;4-validando-uma-sess-o-antes-de-importar&quot;&gt;4. Validando uma sessão antes de importar&lt;/h3&gt;
&lt;p&gt;Antes da gravação definitiva, executei o &lt;code&gt;backfill&lt;/code&gt; em modo &lt;code&gt;dry-run&lt;/code&gt;,&lt;br&gt;
selecionando uma sessão por vez.&lt;/p&gt;
&lt;p&gt;O exemplo abaixo usa um diretório e um identificador ilustrativos.&lt;br&gt;
Substitua-os pelos valores reais da sua instalação:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd &quot;$HOME/Documentos/github/meu-projeto&quot;

export AI_MEMORY_SERVER_URL=http://127.0.0.1:49375

ai-memory backfill \
  --session ses_ID_DA_SESSAO \
  --max-sessions 1 \
  --dry-run \
  --json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O parâmetro &lt;code&gt;--session&lt;/code&gt; restringe a execução a uma sessão específica.&lt;br&gt;
&lt;code&gt;--max-sessions 1&lt;/code&gt; limita o processamento a uma sessão por chamada,&lt;br&gt;
enquanto &lt;code&gt;--dry-run&lt;/code&gt; permite verificar a seleção sem efetivar a&lt;br&gt;
importação.&lt;/p&gt;
&lt;p&gt;Esse cuidado é importante porque a seleção depende do projeto atual. Na&lt;br&gt;
minha execução, quando rodei o comando a partir de &lt;code&gt;~&lt;/code&gt;, o CLI&lt;br&gt;
identificou o projeto como &lt;code&gt;marcos&lt;/code&gt; e não selecionou a sessão desejada.&lt;br&gt;
Executar a partir do diretório original evitou esse problema.&lt;/p&gt;
&lt;h3 id=&quot;5-testando-uma-importa-o-real&quot;&gt;5. Testando uma importação real&lt;/h3&gt;
&lt;p&gt;Depois de validar a seleção, importei uma sessão de teste:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd &quot;$HOME/Documentos/github/meu-projeto&quot;

AI_MEMORY_SERVER_URL=http://127.0.0.1:49375 \
  ai-memory backfill \
    --session ses_ID_DA_SESSAO \
    --max-sessions 1 \
    --json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O resultado da sessão de teste foi:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uma sessão importada.&lt;/li&gt;
&lt;li&gt;542 eventos importados.&lt;/li&gt;
&lt;li&gt;Zero falhas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Como o armazenamento deixou de estar vazio após a primeira importação,&lt;br&gt;
utilizei &lt;code&gt;--force&lt;/code&gt; nas chamadas seguintes. Esse parâmetro permite&lt;br&gt;
executar o &lt;code&gt;backfill&lt;/code&gt; mesmo quando já existem sessões no armazenamento.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;--force&lt;/code&gt; com cuidado, mantendo a seleção explícita da sessão e&lt;br&gt;
conferindo os resultados para não processar mais histórico do que o&lt;br&gt;
pretendido.&lt;/p&gt;
&lt;h3 id=&quot;6-automatizando-as-176-sess-es-restantes&quot;&gt;6. Automatizando as 176 sessões restantes&lt;/h3&gt;
&lt;p&gt;Com o teste concluído, automatizei a importação das demais sessões&lt;br&gt;
elegíveis. O script abaixo lê o relatório de validação, pula a sessão de&lt;br&gt;
teste já importada e registra os resultados em um log.&lt;/p&gt;
&lt;p&gt;Salve como &lt;code&gt;~/backups/opencode/import-restantes.sh&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cat &amp;gt; &quot;$HOME/backups/opencode/import-restantes.sh&quot; &amp;lt;&amp;lt;'BASH'
#!/usr/bin/env bash
set -uo pipefail

REPORT=&quot;$HOME/backups/opencode/session-validation.log&quot;
LOG=&quot;$HOME/backups/opencode/import-restantes.log&quot;
export AI_MEMORY_SERVER_URL=&quot;http://127.0.0.1:49375&quot;

JA_IMPORTADA=&quot;ses_ID_DA_SESSAO_DE_TESTE&quot;

if [[ ! -f &quot;$REPORT&quot; ]]; then
  echo &quot;Relatório não encontrado: $REPORT&quot; &amp;gt;&amp;amp;2
  exit 1
fi

: &amp;gt; &quot;$LOG&quot;

total=0
sucesso=0
falha=0
ignorada=0

while IFS=$'\t' read -r status id dir; do
  [[ &quot;$status&quot; == &quot;OK&quot; ]] || continue
  [[ -n &quot;$id&quot; &amp;amp;&amp;amp; -n &quot;$dir&quot; ]] || continue

  if [[ &quot;$id&quot; == &quot;$JA_IMPORTADA&quot; ]]; then
    ignorada=$((ignorada + 1))
    continue
  fi

  if [[ ! -d &quot;$dir&quot; ]]; then
    echo &quot;ERRO: diretório ausente: $id — $dir&quot; | tee -a &quot;$LOG&quot;
    falha=$((falha + 1))
    continue
  fi

  total=$((total + 1))
  echo &quot;[$total] Importando $id — $dir&quot; | tee -a &quot;$LOG&quot;

  if (
    cd &quot;$dir&quot; &amp;amp;&amp;amp;
      ai-memory backfill \
        --session &quot;$id&quot; \
        --max-sessions 1 \
        --force \
        --json
  ) &amp;gt;&amp;gt; &quot;$LOG&quot; 2&amp;gt;&amp;amp;1; then
    sucesso=$((sucesso + 1))
    echo &quot;OK: $id&quot; | tee -a &quot;$LOG&quot;
  else
    falha=$((falha + 1))
    echo &quot;FALHA: $id — verificar $LOG&quot; | tee -a &quot;$LOG&quot;
  fi
done &amp;lt; &quot;$REPORT&quot;

echo
echo &quot;Importação concluída.&quot;
echo &quot;Processadas: $total | Sucesso: $sucesso | Falhas: $falha | Já importada: $ignorada&quot;
echo &quot;Log: $LOG&quot;

ai-memory status
BASH

chmod +x &quot;$HOME/backups/opencode/import-restantes.sh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Antes de executar:&lt;/strong&gt; substitua &lt;code&gt;ses_ID_DA_SESSAO_DE_TESTE&lt;/code&gt; pelo ID&lt;br&gt;
real da sessão importada no teste. Confira também se o relatório contém&lt;br&gt;
apenas registros de validação no formato esperado e se os diretórios&lt;br&gt;
continuam disponíveis.&lt;/p&gt;
&lt;p&gt;Execute:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&quot;$HOME/backups/opencode/import-restantes.sh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O script percorre somente as entradas &lt;code&gt;OK&lt;/code&gt;, muda para o diretório&lt;br&gt;
original de cada sessão e executa uma importação por chamada. Se uma&lt;br&gt;
sessão falhar, registra a ocorrência e continua com as seguintes.&lt;/p&gt;
&lt;p&gt;Na execução realizada, o script importou 176 sessões sem falhas, além da&lt;br&gt;
sessão de teste importada anteriormente. O resultado total foi de 177&lt;br&gt;
sessões.&lt;/p&gt;
&lt;h3 id=&quot;7-conferindo-os-resultados&quot;&gt;7. Conferindo os resultados&lt;/h3&gt;
&lt;p&gt;Ao final, executei:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;AI_MEMORY_SERVER_URL=http://127.0.0.1:49375 ai-memory status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O armazenamento apresentou os seguintes indicadores:&lt;/p&gt;
&lt;p&gt;  Indicador                                 Resultado&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;  Sessões importadas                              177&lt;br&gt;
  Falhas de importação                              0&lt;br&gt;
  Observações armazenadas                      16.610&lt;br&gt;
  Páginas, incluindo versões anteriores           189&lt;br&gt;
  Embeddings                                      189&lt;br&gt;
  Páginas mais recentes sem embedding               0&lt;br&gt;
  Eventos pendentes no spool                        0&lt;br&gt;
  Espaço utilizado                           26,8 MiB&lt;/p&gt;
&lt;p&gt;A busca textual estava indexada para todas as 189 versões de páginas e&lt;br&gt;
para as 16.610 observações. O modelo local &lt;code&gt;all-MiniLM-L6-v2&lt;/code&gt;, com&lt;br&gt;
vetores de 384 dimensões, estava operacional.&lt;/p&gt;
&lt;p&gt;Para consultar os projetos disponíveis:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ai-memory list-projects
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inicialmente, esse comando retornou &lt;code&gt;404 Not Found&lt;/code&gt; com a versão 2.6.5.&lt;br&gt;
Após atualizar o CLI para a versão 2.6.6, o comando passou a listar&lt;br&gt;
corretamente os projetos.&lt;/p&gt;
&lt;h3 id=&quot;8-problemas-encontrados-e-solu-es&quot;&gt;8. Problemas encontrados e soluções&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;O CLI tentava acessar a porta errada.&lt;/strong&gt;\&lt;br&gt;
A variável &lt;code&gt;AI_MEMORY_SERVER_URL&lt;/code&gt; não estava definida no ambiente. A&lt;br&gt;
solução foi exportar a URL do servidor na porta &lt;code&gt;49375&lt;/code&gt; e persistir a&lt;br&gt;
configuração no &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;O backfill não encontrava a sessão.&lt;/strong&gt;\&lt;br&gt;
O comando estava sendo executado fora do diretório original do projeto.&lt;br&gt;
A solução foi entrar no diretório correto antes de executar a&lt;br&gt;
importação.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;O armazenamento já não estava vazio.&lt;/strong&gt;\&lt;br&gt;
Após a importação inicial, as chamadas seguintes precisaram de &lt;code&gt;--force&lt;/code&gt;&lt;br&gt;
para executar o &lt;code&gt;backfill&lt;/code&gt;. Para limitar o escopo, mantive &lt;code&gt;--session&lt;/code&gt; e&lt;br&gt;
&lt;code&gt;--max-sessions 1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;O comando &lt;code&gt;list-projects&lt;/code&gt; retornava 404.&lt;/strong&gt;\&lt;br&gt;
A atualização do AI Memory para a versão 2.6.6 resolveu o problema&lt;br&gt;
observado, sem necessidade de reimportar as sessões.&lt;/p&gt;
&lt;h3 id=&quot;conclus-o&quot;&gt;Conclusão&lt;/h3&gt;
&lt;p&gt;O processo transformou 177 sessões do OpenCode em uma base local&lt;br&gt;
pesquisável, com 16.610 observações e embeddings gerados. Não houve&lt;br&gt;
falhas de importação na execução registrada.&lt;/p&gt;
&lt;p&gt;O ponto principal não foi apenas executar o &lt;code&gt;backfill&lt;/code&gt;, mas validar as&lt;br&gt;
sessões, preservar o histórico original, respeitar o contexto dos&lt;br&gt;
projetos e registrar os resultados de cada etapa.&lt;/p&gt;
&lt;p&gt;O AI Memory passou a oferecer uma base para recuperar decisões e&lt;br&gt;
investigações anteriores. A próxima etapa é validar essa recuperação em&lt;br&gt;
situações reais de desenvolvimento e manter a integração funcionando&lt;br&gt;
continuamente.&lt;/p&gt;
&lt;h2 id=&quot;codelegion-opencode-aimemory-ia-devtools-llm-engenhariadesoftware&quot;&gt;CodeLegion #OpenCode #AIMemory #IA #DevTools #LLM #EngenhariaDeSoftware&lt;/h2&gt;
&lt;h2 id=&quot;devex&quot;&gt;DevEx&lt;/h2&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/30982/migrando-177-sessoes-do-opencode-para-o-ai-memory-passo-a-passo-com-comandos</guid>
<pubDate>Tue, 13 Oct 2026 20:07:36 +0000</pubDate>
</item>
<item>
<title>Do histórico perdido ao contexto reutilizável: migrando sessões do OpenCode para o AI Memory</title>
<link>https://coderlegion.com/30981/do-historico-perdido-ao-contexto-reutilizavel-migrando-sessoes-do-opencode-para-memory</link>
<description>&lt;p&gt;&lt;strong&gt;Como migrei 177 sessões de desenvolvimento para uma memória local pesquisável, preservando o histórico original e preparando o ambiente para reutilizar conhecimento entre sessões de IA.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;o-problema-cada-sess-o-termina-mas-o-conhecimento-precisa-continuar&quot;&gt;O problema: cada sessão termina, mas o conhecimento precisa continuar&lt;/h3&gt;
&lt;p&gt;Ferramentas de desenvolvimento com IA aceleram tarefas como investigação de incidentes, alterações de infraestrutura, depuração e implementação de funcionalidades. Porém, existe um problema recorrente: boa parte do contexto fica distribuída em sessões anteriores.&lt;/p&gt;
&lt;p&gt;Uma investigação pode envolver dezenas de mensagens, comandos executados, decisões de arquitetura, erros encontrados e soluções validadas. Ao iniciar uma nova sessão, recuperar esse contexto manualmente consome tempo e nem sempre é possível lembrar onde uma decisão foi tomada.&lt;/p&gt;
&lt;p&gt;O objetivo da migração foi transformar o histórico de sessões do OpenCode em uma base local de memória que permita recuperar informações de trabalhos anteriores sem depender exclusivamente da busca manual nas conversas.&lt;/p&gt;
&lt;h3 id=&quot;a-solu-o-ai-memory&quot;&gt;A solução: AI Memory&lt;/h3&gt;
&lt;p&gt;O &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/akitaonrails/ai-memory&quot;&gt;AI Memory&lt;/a&gt; é um projeto voltado à persistência e recuperação de contexto para fluxos de trabalho com IA. Nesta implementação, utilizei a versão 2.6.5, com armazenamento local, indexação textual e embeddings gerados por um modelo local.&lt;/p&gt;
&lt;p&gt;A migração foi realizada em etapas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identificação do banco de dados original do OpenCode.&lt;/li&gt;
&lt;li&gt;Backup do histórico antes de qualquer operação.&lt;/li&gt;
&lt;li&gt;Inventário das sessões e identificação dos diretórios de projeto associados.&lt;/li&gt;
&lt;li&gt;Validação das sessões que ainda correspondiam a diretórios disponíveis.&lt;/li&gt;
&lt;li&gt;Importação individual das sessões para o AI Memory.&lt;/li&gt;
&lt;li&gt;Verificação da indexação, dos embeddings e do estado do armazenamento.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A decisão de importar cada sessão a partir de seu diretório original foi importante: o processo de backfill utiliza o contexto do projeto atual para identificar as sessões elegíveis.&lt;/p&gt;
&lt;h3 id=&quot;preserva-o-e-valida-o-do-hist-rico&quot;&gt;Preservação e validação do histórico&lt;/h3&gt;
&lt;p&gt;O banco original do OpenCode foi mantido intacto. O trabalho foi feito a partir de uma cópia de segurança e de comandos de importação direcionados a cada sessão.&lt;/p&gt;
&lt;p&gt;Durante o inventário, foram identificadas 197 sessões. Desse total, 177 passaram pela validação e foram selecionadas para importação. As outras 20 estavam associadas a diretórios antigos, removidos ou não disponíveis. Como pertenciam a projetos legados que não precisavam fazer parte desta migração, ficaram fora do escopo.&lt;/p&gt;
&lt;p&gt;Antes da importação definitiva, as sessões elegíveis foram submetidas a uma execução de validação em modo &lt;code&gt;dry-run&lt;/code&gt;. Isso permitiu confirmar a seleção sem gravar os dados no armazenamento definitivo.&lt;/p&gt;
&lt;p&gt;A importação foi então automatizada com processamento individual, registro dos resultados em log e tratamento de falhas por sessão.&lt;/p&gt;
&lt;h3 id=&quot;resultado-da-migra-o&quot;&gt;Resultado da migração&lt;/h3&gt;
&lt;p&gt;Ao final do processo, o AI Memory apresentou os seguintes indicadores:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Indicador &lt;/th&gt;&lt;th&gt;Resultado&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Sessões importadas &lt;/td&gt;&lt;td&gt;177&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Falhas na importação &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Observações armazenadas &lt;/td&gt;&lt;td&gt;16.610&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Versões de páginas indexadas &lt;/td&gt;&lt;td&gt;189&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Embeddings gerados &lt;/td&gt;&lt;td&gt;189&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Páginas mais recentes sem embedding &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Eventos pendentes no spool &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Espaço utilizado &lt;/td&gt;&lt;td&gt;26,8 MiB&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;A busca textual (FTS) estava indexada para todas as 189 versões de páginas e para as 16.610 observações. O modelo local &lt;code&gt;all-MiniLM-L6-v2&lt;/code&gt;, com embeddings de 384 dimensões, também estava operacional.&lt;/p&gt;
&lt;p&gt;Esses números confirmam que o histórico validado foi importado e indexado. A etapa seguinte é testar a recuperação de informações de sessões específicas e validar o uso da memória durante novos trabalhos.&lt;/p&gt;
&lt;h3 id=&quot;por-que-manter-a-mem-ria-local-&quot;&gt;Por que manter a memória local?&lt;/h3&gt;
&lt;p&gt;Para este fluxo, manter os dados localmente oferece algumas vantagens práticas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Controle dos dados:&lt;/strong&gt; o armazenamento permanece na máquina, sem exigir que o histórico seja enviado a um serviço externo de memória.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Busca contextual:&lt;/strong&gt; informações de sessões anteriores podem ser recuperadas sem depender apenas da memória da conversa atual.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Baixo consumo de armazenamento:&lt;/strong&gt; a base importada ocupou aproximadamente 26,8 MiB.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Independência do modelo de linguagem:&lt;/strong&gt; a indexação vetorial utiliza um modelo local, embora a geração de respostas por um LLM não esteja habilitada nesta configuração.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rastreabilidade:&lt;/strong&gt; o processo foi executado com logs, validação prévia e contagem de sessões importadas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Memória local não elimina a necessidade de segurança. Bancos de conversas podem conter comandos, caminhos, informações de infraestrutura e outros dados sensíveis. Por isso, backups, permissões de arquivos e políticas de retenção continuam importantes.&lt;/p&gt;
&lt;h3 id=&quot;o-que-ainda-precisa-ser-validado-&quot;&gt;O que ainda precisa ser validado?&lt;/h3&gt;
&lt;p&gt;A importação é apenas uma parte da solução. Para considerar o fluxo pronto para uso contínuo, ainda é necessário:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Testar buscas com assuntos conhecidos, comparando os resultados com as sessões originais.&lt;/li&gt;
&lt;li&gt;Verificar a resolução de um link de memória que permaneceu pendente.&lt;/li&gt;
&lt;li&gt;Avaliar os eventos descartados pela política de captura.&lt;/li&gt;
&lt;li&gt;Confirmar que o serviço inicia automaticamente após reinicializações.&lt;/li&gt;
&lt;li&gt;Validar a integração de captura e recuperação com novas sessões do OpenCode.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Esses testes distinguem uma base importada e indexada de um sistema de memória efetivamente integrado ao fluxo diário de desenvolvimento.&lt;/p&gt;
&lt;h3 id=&quot;conclus-o-1&quot;&gt;Conclusão&lt;/h3&gt;
&lt;p&gt;A migração transformou um histórico de conversas de desenvolvimento em uma base local com 177 sessões importadas, 16.610 observações armazenadas e indexação textual e vetorial operacional.&lt;/p&gt;
&lt;p&gt;O ganho esperado não está apenas em guardar conversas antigas, mas em reduzir o esforço necessário para recuperar decisões, diagnósticos e soluções de trabalhos anteriores. O próximo passo é validar essa recuperação na prática e integrar o AI Memory ao fluxo contínuo de desenvolvimento assistido por IA.&lt;/p&gt;
&lt;h2 id=&quot;codelegion-opencode-aimemory-ia-desenvolvimentodesoftware-devtools-llm-engenhariadesoftware&quot;&gt;CodeLegion #OpenCode #AIMemory #IA #DesenvolvimentoDeSoftware #DevTools #LLM #EngenhariaDeSoftware&lt;/h2&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/30981/do-historico-perdido-ao-contexto-reutilizavel-migrando-sessoes-do-opencode-para-memory</guid>
<pubDate>Tue, 13 Oct 2026 19:55:11 +0000</pubDate>
</item>
<item>
<title>AI Memory no Debian: como integrar memória persistente ao OpenCode com mise, MCP e systemd</title>
<link>https://coderlegion.com/30980/ai-memory-no-debian-como-integrar-memoria-persistente-ao-opencode-com-mise-mcp-e-systemd</link>
<description>&lt;p&gt;Quem utiliza agentes de IA para desenvolver software já percebeu um problema recorrente: a cada nova sessão, parte do contexto se perde. Decisões de arquitetura, particularidades do projeto, comandos utilizados e soluções de problemas anteriores nem sempre estão disponíveis para a próxima conversa.&lt;/p&gt;
&lt;p&gt;Uma alternativa é o &lt;strong&gt;AI Memory&lt;/strong&gt;, projeto open source de Akita que oferece memória persistente para agentes de IA.&lt;/p&gt;
&lt;p&gt;Neste artigo, vamos configurar o AI Memory no Debian e integrá-lo ao OpenCode 2, utilizando &lt;code&gt;mise&lt;/code&gt; para gerenciar a instalação, MCP para comunicação entre os componentes e &lt;code&gt;systemd&lt;/code&gt; para manter o serviço ativo.&lt;/p&gt;
&lt;h3 id=&quot;1-instalando-o-mise-no-debian&quot;&gt;1. Instalando o mise no Debian&lt;/h3&gt;
&lt;p&gt;O mise é um gerenciador de ferramentas e versões que permite instalar e controlar executáveis sem depender exclusivamente dos pacotes da distribuição.&lt;/p&gt;
&lt;p&gt;Instale-o utilizando um dos métodos disponíveis na documentação oficial: &lt;a rel=&quot;nofollow&quot; href=&quot;https://mise.jdx.dev/installing-mise.html&quot;&gt;https://mise.jdx.dev/installing-mise.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Caso o pacote esteja disponível nos repositórios configurados:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt update
sudo apt install mise
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Depois, configure a integração com o Bash:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;echo 'eval &quot;$(mise activate bash)&quot;' &amp;gt;&amp;gt; ~/.bashrc
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Verifique se a instalação está funcionando:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mise --version
mise doctor
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-instalando-o-ai-memory&quot;&gt;2. Instalando o AI Memory&lt;/h3&gt;
&lt;p&gt;Com o mise configurado, instale o AI Memory diretamente do GitHub:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mise use -g github:akitaonrails/ai-memory@2.6.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Inicialize a ferramenta:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ai-memory init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Confirme a versão e o caminho do executável:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ai-memory --version
mise which ai-memory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No meu ambiente, o executável ficou disponível em:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;~/.local/share/mise/installs/github-akitaonrails-ai-memory/latest/ai-memory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A vantagem dessa abordagem é manter a instalação gerenciada pelo mise, facilitando o controle de versões e futuras atualizações.&lt;/p&gt;
&lt;p&gt;Repositório: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/akitaonrails/ai-memory&quot;&gt;https://github.com/akitaonrails/ai-memory&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;3-executando-o-servidor-mcp&quot;&gt;3. Executando o servidor MCP&lt;/h3&gt;
&lt;p&gt;O AI Memory pode disponibilizar suas ferramentas por meio de um servidor HTTP compatível com MCP (Model Context Protocol).&lt;/p&gt;
&lt;p&gt;Para testar o serviço manualmente:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ai-memory serve \
  --transport http \
  --bind 127.0.0.1:49375
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Utilizei a porta &lt;code&gt;49375&lt;/code&gt; porque a &lt;code&gt;49374&lt;/code&gt; já estava ocupada pelo serviço do OpenCode no meu ambiente.&lt;/p&gt;
&lt;p&gt;Em outro terminal, confira a porta:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ss -lntp | grep 49375
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;E teste o endpoint:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -i http://127.0.0.1:49375/mcp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Uma observação importante: uma resposta HTTP isolada não garante que o protocolo MCP esteja funcionando corretamente. Verifique se a porta pertence ao processo &lt;code&gt;ai-memory&lt;/code&gt; e, posteriormente, valide a conexão pelo cliente MCP.&lt;/p&gt;
&lt;h3 id=&quot;4-mantendo-o-ai-memory-ativo-com-systemd&quot;&gt;4. Mantendo o AI Memory ativo com systemd&lt;/h3&gt;
&lt;p&gt;Executar o servidor manualmente funciona para testes, mas não é uma solução adequada para uso contínuo. Se o terminal for fechado, o processo pode ser encerrado.&lt;/p&gt;
&lt;p&gt;Para resolver isso, vamos criar um serviço systemd de usuário.&lt;/p&gt;
&lt;p&gt;Crie o diretório:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir -p ~/.config/systemd/user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Crie o arquivo &lt;code&gt;~/.config/systemd/user/ai-memory.service&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;[Unit]
Description=AI Memory MCP Server
After=default.target

[Service]
Type=simple
ExecStart=/home/marcos/.local/share/mise/installs/github-akitaonrails-ai-memory/latest/ai-memory serve --transport http --bind 127.0.0.1:49375
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O caminho em &lt;code&gt;ExecStart&lt;/code&gt; deve corresponder ao resultado de &lt;code&gt;mise which ai-memory&lt;/code&gt;. Isso evita depender das variáveis de ambiente do Bash, que podem não estar disponíveis nos serviços systemd.&lt;/p&gt;
&lt;p&gt;Agora, carregue e habilite o serviço:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl --user daemon-reload
systemctl --user enable --now ai-memory.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para permitir que os serviços do usuário iniciem no boot mesmo sem uma sessão interativa aberta:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo loginctl enable-linger &quot;$USER&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Confira o estado:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl --user status ai-memory.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;E consulte os logs:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;journalctl --user -u ai-memory.service -n 50 --no-pager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Com isso, o systemd passa a gerenciar o processo e tenta reiniciá-lo quando ocorre uma falha. Aqui incluímos um ponto importante que sempre terá um serviço em execução no seu SO, no entanto, uma vez que gerenciamos via serviço, podemos fazer 'enable' e 'disable' quando necessário, por isso o caminho de gerenciar via serviço é um bom caminho a não ter de ficar iniciando o serviço manualmente.&lt;/p&gt;
&lt;h3 id=&quot;5-integrando-o-ai-memory-ao-opencode-2&quot;&gt;5. Integrando o AI Memory ao OpenCode 2&lt;/h3&gt;
&lt;p&gt;Com o servidor ativo, precisamos registrar o endpoint MCP no OpenCode.&lt;/p&gt;
&lt;p&gt;No meu ambiente, utilizei:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenCode &lt;code&gt;v2.0.28&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;AI Memory &lt;code&gt;2.6.5&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Endpoint local &lt;code&gt;http://127.0.0.1:49375/mcp&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Como a estrutura de configuração varia entre versões do OpenCode, utilizei o instalador específico para a versão 2:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ai-memory install-mcp \
  --client opencode2 \
  --server-url http://127.0.0.1:49375/mcp \
  --apply
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;O instalador informa qual arquivo foi atualizado. No meu ambiente, a configuração fica em:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;~/.config/opencode/opencode.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;É importante preservar os outros servidores MCP já configurados e evitar cadastrar o mesmo servidor duas vezes.&lt;/p&gt;
&lt;h3 id=&quot;6-configurando-os-hooks&quot;&gt;6. Configurando os hooks&lt;/h3&gt;
&lt;p&gt;Disponibilizar ferramentas MCP não significa necessariamente que o agente salvará e recuperará informações automaticamente em todas as sessões.&lt;/p&gt;
&lt;p&gt;Para investigar a integração de ciclo de vida, consulte as opções suportadas pela versão instalada:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ai-memory install-hooks --help
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Se a versão instalada oferecer suporte ao OpenCode 2, utilize os argumentos documentados pelo próprio comando para instalar os hooks. Não presuma que os parâmetros ou o formato de plugins de versões anteriores sejam compatíveis.&lt;/p&gt;
&lt;p&gt;O objetivo é aproximar duas funcionalidades diferentes: disponibilizar memória para consulta e permitir que o agente utilize essa memória durante o fluxo de trabalho.&lt;/p&gt;
&lt;h3 id=&quot;7-diagn-stico-de-problemas&quot;&gt;7. Diagnóstico de problemas&lt;/h3&gt;
&lt;p&gt;Durante a configuração, encontrei um conflito importante: a porta &lt;code&gt;49374&lt;/code&gt; pertencia ao processo &lt;code&gt;opencode serve --service&lt;/code&gt;, e não ao AI Memory.&lt;/p&gt;
&lt;p&gt;O comando abaixo ajudou a identificar o responsável pela porta:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ss -lntp | grep -E '49374|49375'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Também é útil conferir os processos:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ps aux | grep -E '[a]i-memory|[o]pencode'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Se o serviço systemd falhar, consulte:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl --user status ai-memory.service --no-pager -l
journalctl --user -u ai-memory.service -n 50 --no-pager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Um erro &lt;code&gt;ExecMainStatus=203&lt;/code&gt; indica que o systemd não conseguiu executar o processo. Nesse caso, confira o caminho configurado em &lt;code&gt;ExecStart&lt;/code&gt; e compare-o com:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mise which ai-memory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Por fim, valide que o endpoint não está retornando a interface web do OpenCode:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -i http://127.0.0.1:49375/mcp
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;8-comandos-teis-para-o-dia-a-dia&quot;&gt;8. Comandos úteis para o dia a dia&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Iniciar
systemctl --user start ai-memory

# Reiniciar
systemctl --user restart ai-memory

# Parar
systemctl --user stop ai-memory

# Consultar o status
systemctl --user status ai-memory

# Acompanhar os logs
journalctl --user -u ai-memory -f

# Verificar a porta
ss -lntp | grep 49375
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;conclus-o-2&quot;&gt;Conclusão&lt;/h3&gt;
&lt;p&gt;Integrar o AI Memory ao OpenCode envolve mais do que cadastrar um endpoint MCP. É necessário gerenciar a instalação, manter o servidor ativo, configurar corretamente o cliente e validar o comportamento real da integração.&lt;/p&gt;
&lt;p&gt;A combinação de mise, systemd e MCP fornece uma base organizada para executar a ferramenta localmente no Debian. O próximo passo é validar o uso efetivo da memória nas sessões e ajustar os hooks de acordo com as capacidades da versão instalada.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Referências&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI Memory: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/akitaonrails/ai-memory&quot;&gt;https://github.com/akitaonrails/ai-memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;mise: &lt;a rel=&quot;nofollow&quot; href=&quot;https://mise.jdx.dev/&quot;&gt;https://mise.jdx.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenCode: &lt;a rel=&quot;nofollow&quot; href=&quot;https://opencode.ai/docs/&quot;&gt;https://opencode.ai/docs/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/30980/ai-memory-no-debian-como-integrar-memoria-persistente-ao-opencode-com-mise-mcp-e-systemd</guid>
<pubDate>Tue, 13 Oct 2026 19:09:39 +0000</pubDate>
</item>
<item>
<title>OpenCode Not Working in Windows 11: CLI + Desktop Both Fail on ConfigInvalidError — Cause and Fix</title>
<link>https://coderlegion.com/27644/opencode-not-working-in-windows-11-cli-desktop-both-fail-configinvaliderror-cause-and-fix</link>
<description>&lt;p&gt;&lt;strong&gt;Environment:&lt;/strong&gt; Windows 11 Pro Insider Preview (build 10.0.26300), OpenCode CLI v1.18.23, OpenCode Desktop v1.18.25, Node.js v26.7.0.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Symptom:&lt;/strong&gt; OpenCode Not Working — both the CLI and the separately-installed Desktop app fail to start a session, immediately, on every launch attempt.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=9148392891076243846&quot; alt=&quot;OpenCode not working in Windows 11 — technical diagram of CLI and Desktop both failing on ConfigInvalidError&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;reproduction&quot;&gt;Reproduction&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ opencode --version
1.18.23
$ opencode
Configuration is invalid at C:\Users\istiqur\.config\opencode\agents\blog-writer.md
↳ Expected object | undefined, got [&quot;Read&quot;,&quot;Write&quot;,&quot;Edit&quot;,&quot;Grep&quot;,&quot;Glob&quot;] tools
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The CLI's validator names the exact file and field. Compare against the Desktop app's &lt;code&gt;renderer.log&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[error]  Failed to load sessions Error: ConfigInvalidError
[error]  Failed to load sessions Error: ConfigInvalidError
[error]  Failed to finish bootstrap instance Error: ConfigInvalidError
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No file path, no field name — same failure class, far less actionable output.&lt;/p&gt;
&lt;h3 id=&quot;root-cause&quot;&gt;Root Cause&lt;/h3&gt;
&lt;p&gt;Five custom subagent &lt;code&gt;.md&lt;/code&gt; files under &lt;code&gt;~/.config/opencode/agents/&lt;/code&gt; declared &lt;code&gt;tools:&lt;/code&gt; as a YAML sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;tools:
  - Read
  - Write
  - Edit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://opencode.ai/docs/config/&quot;&gt;OpenCode's config schema&lt;/a&gt; requires &lt;code&gt;tools&lt;/code&gt; as a mapping (tool name → boolean):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;tools:
  read: true
  write: true
  edit: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both shapes are valid YAML in isolation — &lt;a rel=&quot;nofollow&quot; href=&quot;https://yaml.org/spec/1.2.2/&quot;&gt;per the YAML 1.2.2 spec&lt;/a&gt;, a sequence and a mapping are distinct node types, so the file parses fine and only fails when a stricter schema inspects the field. All five files carried the identical defect (list format, apparently ported from a different AI coding assistant's subagent convention), confirming a batch-import mismatch rather than an isolated typo.&lt;/p&gt;
&lt;p&gt;Affected files:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;File &lt;/th&gt;&lt;th&gt;Declared tools&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;blog-writer.md&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Read, Write, Edit, Grep, Glob&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;blog-seo.md&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Read, Grep, Glob&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;blog-reviewer.md&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Read, Grep, Glob&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;blog-researcher.md&lt;/code&gt; &lt;/td&gt;&lt;td&gt;WebSearch, WebFetch, Read, Grep, Glob&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;blog-translator.md&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Read, Write, Edit, Glob, Grep&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=3901805291713832268&quot; alt=&quot;OpenCode not working fix — converting a YAML list tools field to the YAML map format required by OpenCode's schema&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;why-it-broke-both-applications&quot;&gt;Why It Broke Both Applications&lt;/h3&gt;
&lt;p&gt;OpenCode CLI and OpenCode Desktop are separate installers (&lt;code&gt;AppData\Roaming\npm\opencode&lt;/code&gt; vs &lt;code&gt;AppData\Local\Programs\@opencode-aidesktop\OpenCode.exe&lt;/code&gt;) with independent version numbers and log directories. They share the same config root, &lt;code&gt;~/.config/opencode/&lt;/code&gt;, and both boot the same local sidecar server at startup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[info]  spawning sidecar { url: 'http://127.0.0.1:11956' }
[info]  server ready { url: 'http://127.0.0.1:11956' }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The sidecar itself starts cleanly in both cases (&lt;code&gt;main.log&lt;/code&gt; shows no errors) — the failure occurs specifically when the app asks the running server to enumerate the agents directory and receives the validation error back. Config errors introduced through either surface (CLI, direct file edit, another tool) will therefore surface identically on both — they are not independent configuration domains.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.youtube.com/watch?v=jZcRgkG01Gg&quot;&gt;Watch the full breakdown on video&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;fix&quot;&gt;Fix&lt;/h3&gt;
&lt;p&gt;Frontmatter-only change, one line per file:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-diff&quot;&gt; tools:
-  - Read
-  - Write
-  - Edit
+  Read: true
+  Write: true
+  Edit: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apply to all five affected files, preserving tool names and case. No reinstall, no cache invalidation, no plugin reset required.&lt;/p&gt;
&lt;h3 id=&quot;verification&quot;&gt;Verification&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ opencode
# TUI launches cleanly, 0 matches for &quot;invalid&quot;/&quot;error&quot; in captured output
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For Desktop: confirm no stale &lt;code&gt;opencode&lt;/code&gt;-named process is running, force-relaunch, and check the &lt;strong&gt;newest&lt;/strong&gt; log session — not the first one alphabetically or chronologically listed. The pre-fix log session will still show the old errors and can easily be mistaken for a failed fix if you don't check its own start timestamp against the fix's file-mtime.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Check &lt;/th&gt;&lt;th&gt;Before &lt;/th&gt;&lt;th&gt;After&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;CLI startup &lt;/td&gt;&lt;td&gt;Fatal &lt;code&gt;ConfigInvalidError&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Clean launch&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Desktop &lt;code&gt;renderer.log&lt;/code&gt; &lt;/td&gt;&lt;td&gt;6 error entries &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Desktop &lt;code&gt;main.log&lt;/code&gt; &lt;/td&gt;&lt;td&gt;No errors (sidecar itself was fine) &lt;/td&gt;&lt;td&gt;No errors&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Bootstrap &lt;/td&gt;&lt;td&gt;Failed &lt;/td&gt;&lt;td&gt;Succeeded&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=3442009814371933697&quot; alt=&quot;Before and after bar chart showing OpenCode not working errors dropping from six to zero once the tools field was fixed&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;related-finding-not-the-root-cause-&quot;&gt;Related Finding (Not the Root Cause)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;opencode.json&lt;/code&gt; was found to store MCP service API keys in plaintext. Unrelated to this failure, but worth an audit pass on any OpenCode install — keep such config files out of version control, source keys from environment variables where possible.&lt;/p&gt;
&lt;h3 id=&quot;takeaways-for-anyone-running-multiple-ai-coding-assistants&quot;&gt;Takeaways for Anyone Running Multiple AI Coding Assistants&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Subagent/plugin config schemas are not interchangeable between vendors, even with near-identical file conventions (Markdown + YAML frontmatter, &lt;code&gt;tools:&lt;/code&gt; field present in both).&lt;/li&gt;
&lt;li&gt;Eager, whole-config, fail-closed validation means a single malformed file can abort every entry point, not just the misconfigured agent.&lt;/li&gt;
&lt;li&gt;A CLI and a GUI application sharing one config root will share failure modes, regardless of separate installers/versions.&lt;/li&gt;
&lt;li&gt;Reproduce GUI failures at the CLI first when a CLI equivalent exists — error verbosity is often not consistent across surfaces of the same product.&lt;/li&gt;
&lt;li&gt;Timestamp-check any log before trusting its contents during verification.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=2117638333071478380&quot; alt=&quot;Three lessons learned from OpenCode not working, covering subagent format mismatches, blast radius, and stale log timestamps&quot;&gt;&lt;/p&gt;
&lt;p&gt;Full writeup (complete diffs, appendix, environment fingerprint): &lt;a rel=&quot;nofollow&quot; href=&quot;https://istiquritconsultant.com/workflow-optimization-blogs/opencode-not-working-windows-11/&quot;&gt;https://istiquritconsultant.com/workflow-optimization-blogs/opencode-not-working-windows-11/&lt;/a&gt; — more postmortems: &lt;a rel=&quot;nofollow&quot; href=&quot;https://istiquritconsultant.com/workflow-optimization-blogs/&quot;&gt;https://istiquritconsultant.com/workflow-optimization-blogs/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This topic was picked by newsletter vote (69% vs. 13% and 18% for two other incidents). Suggestions for future postmortems welcome — comment below or join the &lt;a rel=&quot;nofollow&quot; href=&quot;https://istiquritconsultant.com/no-spam-tech-newsletter/&quot;&gt;newsletter&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;find-me-elsewhere&quot;&gt;Find Me Elsewhere&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/istiquritconsultant/blog-archive&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://remoteseoconsultant.blogspot.com/&quot;&gt;Blogger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://sites.google.com/view/remotegtmmanager/&quot;&gt;Google Sites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://istiqur-it-consultant.hashnode.dev/&quot;&gt;Hashnode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://remoteseoconsultant.medium.com/&quot;&gt;Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/remoteseoconsultant&quot;&gt;Dev.to&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://istiquritconsultant.substack.com/&quot;&gt;Substack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://pastebin.com/u/remotegtmmanager&quot;&gt;Pastebin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/md-istiqur-rahman-rabby/&quot;&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/mdistiqurrahman&quot;&gt;X (Twitter)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/27644/opencode-not-working-in-windows-11-cli-desktop-both-fail-configinvaliderror-cause-and-fix</guid>
<pubDate>Fri, 18 Sep 2026 14:09:54 +0000</pubDate>
</item>
</channel>
</rss>