Skip to content

feat: add local-deploy (dl) setup script and documentation#1

Merged
felippepestana merged 3 commits intomainfrom
claude/setup-local-deploy-env-PO420
Mar 12, 2026
Merged

feat: add local-deploy (dl) setup script and documentation#1
felippepestana merged 3 commits intomainfrom
claude/setup-local-deploy-env-PO420

Conversation

@felippepestana
Copy link
Copy Markdown
Owner

Instala o dl CLI v1.2.0 (local-deploy.github.io) como ferramenta de
deploy local para o ambiente de desenvolvimento AIOX.

  • setup-local-deploy.sh — script automatizado de instalação do dl
  • doc/local-deploy.md — documentação de uso, comandos e integração com AIOX

Resultado da instalação no ambiente:

  • Docker 29.2 + Docker Compose v2 (plugin 5.0.2) verificados
  • dl v1.2.0 instalado em /usr/local/bin/dl (linux/amd64)

https://claude.ai/code/session_01VvEVwiYjmAwL3G8cQG5nuy

claude added 3 commits March 11, 2026 23:03
Instala o dl CLI v1.2.0 (local-deploy.github.io) como ferramenta de
deploy local para o ambiente de desenvolvimento AIOX.

- setup-local-deploy.sh — script automatizado de instalação do dl
- doc/local-deploy.md — documentação de uso, comandos e integração com AIOX

Resultado da instalação no ambiente:
- Docker 29.2 + Docker Compose v2 (plugin 5.0.2) verificados
- dl v1.2.0 instalado em /usr/local/bin/dl (linux/amd64)

https://claude.ai/code/session_01VvEVwiYjmAwL3G8cQG5nuy
Cria ambiente de conversação completo para interação com os squads AIOX.
O chatbot carrega dinamicamente todos os agentes das pastas squads/*/agents/*.md
e os expõe como personas conversacionais via claude-opus-4-6.

Funcionalidades:
- Seleção interativa de agente (8 squads, 73 agentes carregados)
- Streaming de respostas token a token
- Upload de arquivos via Files API (PDF, imagens, CSV, TXT, JSON)
- Troca de agente em tempo real sem perder histórico
- Comandos: /help /agent /upload /files /reset /status /exit
- Cleanup automático de arquivos ao encerrar sessão
- Adaptive thinking (claude-opus-4-6)

Estrutura:
  chatbot/src/agents.ts — carregador de agentes dos .md
  chatbot/src/chat.ts   — sessão de streaming com Files API
  chatbot/src/files.ts  — upload/delete via Files API beta
  chatbot/src/index.ts  — CLI interativa com cores ANSI
  chatbot/start.sh      — script de inicialização

Resultado de smoke test:
- 8 squads carregados, 73 agentes disponíveis
- Menu de seleção renderizado corretamente
- TypeScript compilado sem erros

https://claude.ai/code/session_01VvEVwiYjmAwL3G8cQG5nuy
- Add Express 5 web server (server.ts) with REST API + SSE chat endpoint
- Mobile-first responsive UI: drawer sidebar, hamburger menu, swipe-to-close
- Safe-area insets (env(safe-area-inset-*)) for notched phones
- 46px touch targets, autocapitalize/autocorrect on textarea
- File upload via Multer 2 + Anthropic Files API integration
- Dockerfile for deployment (build context = repo root)
- docker-compose.chatbot.yml for easy local/cloud deployment
- web-start.sh script to start web interface

https://claude.ai/code/session_01XXsrRinWBHmRBDd7X9yci8
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Este pull request aprimora o ambiente de desenvolvimento AIOX ao introduzir o 'dl CLI' para gerenciamento de deploy local baseado em Docker Compose, simplificando a configuração de serviços e replicando ambientes de produção. Além disso, ele adiciona um novo chatbot interativo, construído em TypeScript, que permite aos usuários conversar com agentes AIOX, fazer upload de arquivos e gerenciar sessões de chat de forma eficiente, tanto via linha de comando quanto por uma interface web.

Highlights

  • Configuração de Ambiente de Desenvolvimento Local: Introduzido um script de configuração 'setup-local-deploy.sh' para instalar o 'dl CLI' (local-deploy) versão 1.2.0, facilitando o ambiente de desenvolvimento local AIOX.
  • Documentação do 'dl CLI': Adicionada documentação detalhada em 'doc/local-deploy.md' sobre o uso, comandos e integração do 'dl CLI' com o AIOX.
  • Novo Chatbot AIOX: Implementado um novo chatbot em TypeScript ('chatbot/') com interfaces CLI e web, suportando streaming, upload de arquivos via Anthropic Files API, troca de agentes em tempo real e histórico de sessão.
  • Integração Docker para o Chatbot: Incluída a configuração Docker para o chatbot ('chatbot/Dockerfile', 'docker-compose.chatbot.yml'), permitindo fácil implantação e gerenciamento.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .gitignore
    • Adicionadas entradas para ignorar 'node_modules' e 'dist' do diretório 'chatbot'.
  • chatbot/Dockerfile
    • Adicionado um Dockerfile para construir a imagem do chatbot, configurando o ambiente Node.js, instalando dependências, compilando TypeScript e copiando squads.
  • chatbot/README.md
    • Adicionada documentação abrangente para o chatbot, detalhando pré-requisitos, início rápido, comandos, formatos de arquivo suportados, agentes disponíveis, exemplo de sessão e arquitetura.
  • chatbot/package-lock.json
    • Adicionado o arquivo de lock de dependências do Node.js para o chatbot.
  • chatbot/package.json
    • Adicionado o arquivo de configuração do pacote Node.js para o chatbot, incluindo scripts de build/start e dependências.
  • chatbot/src/agents.ts
    • Adicionado um módulo para carregar e gerenciar agentes de IA de arquivos markdown, incluindo extração de metadados e construção de prompts de sistema.
  • chatbot/src/chat.ts
    • Adicionado um módulo para gerenciar sessões de chat com a API Anthropic, suportando streaming de respostas e blocos de conteúdo de arquivo.
  • chatbot/src/files.ts
    • Adicionado um módulo para lidar com upload de arquivos para a Anthropic Files API, incluindo tipos MIME suportados e exclusão de arquivos.
  • chatbot/src/index.ts
    • Adicionado o ponto de entrada principal da interface de linha de comando (CLI) do chatbot, gerenciando entrada do usuário, comandos, seleção de agente e interação com a sessão de chat.
  • chatbot/src/server.ts
    • Adicionado um servidor web Express para o chatbot, fornecendo streaming SSE, upload de arquivos, APIs de gerenciamento de agentes e uma interface de usuário HTML incorporada.
  • chatbot/start.sh
    • Adicionado um script shell para iniciar o chatbot CLI, incluindo instalação de dependências e compilação TypeScript.
  • chatbot/tsconfig.json
    • Adicionada a configuração TypeScript para o projeto do chatbot.
  • chatbot/web-start.sh
    • Adicionado um script shell para iniciar o chatbot web, incluindo instalação de dependências e compilação TypeScript.
  • doc/local-deploy.md
    • Adicionada documentação para a ferramenta 'local-deploy (dl)', cobrindo seu propósito, pré-requisitos, instalação, fluxo de trabalho, comandos, configuração HTTPS, stacks suportadas e integração com AIOX.
  • docker-compose.chatbot.yml
    • Adicionado um arquivo Docker Compose para definir e executar o serviço de chatbot, incluindo contexto de build, mapeamento de portas, variáveis de ambiente e verificações de saúde.
  • setup-local-deploy.sh
    • Adicionado um script shell para automatizar a instalação e configuração da ferramenta 'local-deploy (dl)', incluindo verificações do Docker e instalação de certificado CA.
Activity
  • O autor felippepestana criou este pull request para adicionar o setup do 'local-deploy (dl)' e a documentação correspondente, além de um novo chatbot.
  • Uma sessão de código no Claude.ai (https://claude.ai/code/session_01VvEVwiYjmAwL3G8cQG5nuy) foi referenciada, indicando o processo de desenvolvimento ou experimentação.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Este pull request adiciona a configuração e documentação para o local-deploy (dl), juntamente com um novo chatbot com interfaces CLI e web. A implementação geral é de alta qualidade, especialmente os scripts de shell e a estrutura do projeto do chatbot. No entanto, identifiquei algumas questões críticas que precisam ser abordadas, principalmente um bug no tratamento de upload de arquivos na interface web que impede a análise correta de imagens, e uma falha na configuração do Dockerfile que tornará o contêiner 'unhealthy'. Também há algumas sugestões de melhoria para otimizar a imagem Docker, melhorar a manutenibilidade do código TypeScript e remover redundâncias.

Comment on lines +26 to +27
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/ || exit 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

O HEALTHCHECK utiliza wget, que não está disponível na imagem base node:22-alpine. Isso fará com que a verificação de saúde falhe e o contêiner seja marcado como "unhealthy", podendo ser reiniciado em loop por orquestradores. Para corrigir, instale o wget na imagem antes da instrução HEALTHCHECK.

RUN apk add --no-cache wget

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD wget -qO- http://localhost:3000/ || exit 1

Comment on lines +159 to +164
const pendingFiles = pendingFileIds.map((id) => ({
fileId: id,
filename: id,
mimeType: "application/octet-stream",
sizeBytes: 0,
}));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Existe um bug no tratamento de arquivos na API web. Ao receber os fileIds do cliente, o servidor cria objetos UploadedFile com um mimeType genérico (application/octet-stream). Isso faz com que todos os arquivos, incluindo imagens, sejam tratados como documentos genéricos pela API da Anthropic, o que impede a análise correta de imagens.

A solução é armazenar o objeto UploadedFile completo na sessão do servidor no momento do upload e recuperá-lo usando o fileId na chamada de chat.

Sugestão de correção:

  1. Altere o tipo da sessão para armazenar o objeto UploadedFile completo:
    const sessions = new Map<
      string,
      { session: ChatSession; files: UploadedFile[] } // Alterado de fileIds: string[]
    >();
  2. Em /api/upload, armazene o objeto completo:
    const entry = getOrCreateSession(sessionId, agentId);
    entry.files.push(uploaded); // Alterado de entry.fileIds.push(uploaded.fileId)
  3. Em /api/chat, recupere os objetos completos em vez de criá-los de forma fictícia:
    const pendingFileIds: string[] = rawFileIds
      ? rawFileIds.split(",").filter(Boolean)
      : [];
    
    const pendingFiles = entry.files.filter(f => pendingFileIds.includes(f.fileId));

Comment on lines +12 to +19
RUN npm install

# Copia source TypeScript e configs
COPY chatbot/tsconfig.json ./
COPY chatbot/src/ ./src/

# Compila TypeScript
RUN npx tsc && npm prune --omit=dev
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Este Dockerfile pode ser otimizado usando um build multi-stage. Isso resulta em uma imagem final menor e mais segura, pois as devDependencies e os arquivos intermediários da compilação não são incluídos na imagem final.

Exemplo de implementação:

# Estágio de build
FROM node:22-alpine AS builder
WORKDIR /app/chatbot
COPY chatbot/package*.json ./
RUN npm install
COPY chatbot/tsconfig.json ./
COPY chatbot/src/ ./src/
RUN npx tsc

# Estágio final
FROM node:22-alpine
WORKDIR /app/chatbot
COPY chatbot/package*.json ./
RUN npm install --omit=dev

# Copia apenas os artefatos compilados do estágio de build
COPY --from=builder /app/chatbot/dist ./dist

# Copia squads para o path correto
COPY squads/ /app/squads/

EXPOSE 3000

# ... (resto do arquivo)

Comment on lines +71 to +80
const stream = (this.client.beta.messages as any).stream(
{
model: MODEL,
max_tokens: 8192,
thinking: { type: "adaptive" },
system: this.agent.systemPrompt,
messages,
},
{ headers: { "anthropic-beta": "files-api-2025-04-14" } }
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

O código utiliza as any para contornar a tipagem de funcionalidades beta do SDK da Anthropic e hardcode a string do cabeçalho beta em múltiplos locais (files.ts, chat.ts). Para melhorar a manutenibilidade e segurança, sugiro:

  1. Extrair a string do cabeçalho para uma constante.
  2. Adicionar um comentário explicando a necessidade do as any para referência futura.

Exemplo:

// No topo do arquivo
const ANTHROPIC_BETA_HEADER = { 'anthropic-beta': 'files-api-2025-04-14' };

// ...

// Uso do 'as any' é necessário pois a API de Files ainda está em beta
// e os tipos podem não estar totalmente estáveis no SDK.
const stream = (this.client.beta.messages as any).stream(
  {
    // ...
  },
  { headers: ANTHROPIC_BETA_HEADER }
);

Comment on lines +22 to +34
const c = {
reset: "\x1b[0m",
bold: "\x1b[1m",
dim: "\x1b[2m",
cyan: "\x1b[36m",
green: "\x1b[32m",
yellow: "\x1b[33m",
blue: "\x1b[34m",
magenta: "\x1b[35m",
red: "\x1b[31m",
white: "\x1b[37m",
bgBlue: "\x1b[44m",
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

O arquivo define manualmente códigos de cores ANSI, mas a dependência chalk já está incluída no package.json. Utilizar chalk tornaria o código mais legível, robusto e consistente com as dependências do projeto, além de lidar automaticamente com a detecção de suporte a cores no terminal.

Sugestão:

import chalk from 'chalk';

// Substituir o objeto 'c' por chamadas diretas ao chalk
function header(text: string): string {
  return `\n${chalk.bold.cyan(text)}`;
}

function success(text: string): string {
  return `${chalk.green('✓')} ${text}`;
}
// ... e assim por diante para as outras funções de cor.

Comment on lines +14 to +19
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

A diretiva healthcheck neste arquivo é redundante, pois já está definida no Dockerfile. Embora não cause um erro por serem idênticas, a melhor prática é definir o healthcheck na imagem (no Dockerfile) para que seja portável. Manter a definição em apenas um lugar simplifica a manutenção. Sugiro remover a seção healthcheck deste arquivo.

@felippepestana felippepestana merged commit efafa9f into main Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants