Skip to content

Latest commit

 

History

History
356 lines (255 loc) · 18.5 KB

File metadata and controls

356 lines (255 loc) · 18.5 KB

Crossbar Technical Roadmap

Este documento é o Manual de Execução Técnica do Crossbar. Ele traduz a visão do original_plan.md em tarefas de engenharia atômicas, granulares e verificáveis.

Status Atual: v1.14.0 (Build tooling & quality gates standardization) Próximo Ciclo: v1.14.1+ (Tray Icon Phases 2-3)

Nota: Epics completadas foram movidas para ROADMAP.archive.done.md.


🔍 Auditoria do Estado Atual (v1.4.0)

Antes de avançar, reconhecemos o que existe e o que falta para atingir a promessa do "Write Once, Run Everywhere".

✅ O que está Sólido

  • Core Architecture: PluginManager e ScriptRunner funcionam bem.
  • Documentation: CODEBASE.md provides a comprehensive architectural guide.
  • Refresh Engine: RefreshService unificado gerencia atualizações periódicas, manuais e background de forma consistente.
  • CLI Foundation: Estrutura de comandos e parser de argumentos robustos.
  • UI Desktop: Janela principal e abas implementadas.
  • Tray: Fixes for initialization race conditions and support for multi-icon SNI.
  • Configuration Engine: Persistência, UI e injeção de variáveis implementados.
  • Configuration Engine v1.1: Campos avançados de schema (date, time, datetime, url, path, textarea, slider) suportados na UI com validação.
  • Mobile Widgets: Integração nativa com Android (XML/Receiver) e iOS (WidgetKit/SwiftUI) via home_widget.
  • Mobile Stability: Cache persistente do crossbar.web no mobile e proteção contra varreduras vazias de plugins.
  • Lua API: Helpers web/env/config/json integrados nos plugins de exemplo.
  • Lua-First Samples: Todos os 26 sample plugins são Lua-only (ADR-014), UI simplificada sem dropdown de linguagem.
  • Marketplace: Sistema de busca e instalação via GitHub implementado (MarketplaceService).

🚧 O que é "Fachada" (Precisa de Implementação)

  • Tray Avançado: Modos "Smart Collapse" e "Overflow" são apenas enums sem lógica.
  • API Gaps: Comando --location (geocoding) não tem lógica implementada.

🎯 Epic v1.1.0: The Configuration Engine (Concluído)

Objetivo: Permitir que plugins declarem configurações (JSON), o usuário preencha (UI), e o sistema injete (ENV vars) com segurança.

Fase 1: Persistência e Segurança

  • Criar Service: lib/services/plugin_config_service.dart.
    • Implementar loadValues(pluginId) lendo de ~/.crossbar/configs/.
    • Implementar saveValues(pluginId, map) escrevendo JSON.
    • Integrar flutter_secure_storage para detectar chaves definidas como type: password no schema e salvar separadamente.
  • Vincular Plugin: Em lib/core/plugin_manager.dart:
    • No método _createPluginFromFile, verificar existência de [plugin].config.json.
    • Parsear JSON para PluginConfig object.
    • Adicionar campo PluginConfig? config ao model Plugin.
  • Teste Unitário: test/unit/services/plugin_config_service_test.dart cobrindo criptografia e I/O.

Fase 2: Injeção de Variáveis

  • Update Runner: Em lib/core/script_runner.dart:
    • Injetar PluginConfigService no construtor.
    • No método run, chamar loadValues.
    • Mesclar valores carregados ao mapa environment passado para Process.start.
  • Teste Funcional: Criar test/functional/fixtures/env_dump.sh e validar se variáveis salvas aparecem no STDOUT.

Fase 3: Conexão UI

  • Plugins Tab: Em lib/ui/tabs/plugins_tab.dart:
    • Adicionar botão "Configurar" (ícone engrenagem) se plugin.config != null.
    • Carregar valores atuais antes de abrir o dialog.
    • Chamar saveValues no callback onSave do PluginConfigDialog.

📱 Epic v1.2.0: Mobile Mastery (Widgets & Services) (Concluído)

Objetivo: Transformar o Crossbar em um cidadão de primeira classe no Android e iOS, usando o package home_widget corretamente.

Fase 1: Android Native (XML & Receiver)

  • Layouts: Criar arquivos XML em android/app/src/main/res/layout/:
    • widget_layout_small.xml (1x1: Ícone + Texto curto).
    • widget_layout_medium.xml (2x1: Ícone + Texto + 1 Ação).
    • widget_layout_large.xml (Lista/Grid para menu items).
  • Kotlin Provider: Criar CrossbarWidgetProvider.kt estendendo HomeWidgetProvider.
    • Implementar lógica de atualização via RemoteViews.
    • Mapear dados do JSON (salvo pelo Flutter) para os IDs do layout XML.
  • Manifest: Registrar o receiver e o provider no AndroidManifest.xml.

Fase 2: iOS Native (WidgetKit)

  • XCode Target: Adicionar target "Widget Extension" ao projeto iOS.
  • App Groups: Configurar App Groups no XCode (Runner + Widget) para compartilhamento de dados UserDefaults.
  • SwiftUI View: Implementar CrossbarWidget.swift.
    • Criar TimelineProvider que lê JSON do UserDefaults (via home_widget).
    • Desenhar View adaptativa (family: .systemSmall, .systemMedium).

Fase 3: Widget Service Logic

  • Serialização: Em lib/services/widget_service.dart:
    • Implementar updateWidget(pluginId, output).
    • Serializar PluginOutput para formato plano (chave/valor) que o home_widget consome.
    • Chamar HomeWidget.updateWidget com o nome correto do provider.
  • Background Sync: Implementado via WorkManager para atualização de widgets em background (Android).
    • Criado lib/services/background_service.dart com callbackDispatcher
    • Tarefa periódica de 15 minutos para atualizar widgets
    • Suporta plugins Lua, YAML e Dart (sem dependências externas)

🖥️ Epic v1.3.0: Advanced Desktop UI

Objetivo: Polimento da experiência desktop e gerenciamento avançado de ícones de bandeja.

Fase 1: Global Hotkey ✅

  • Dependência: hotkey_manager: ^0.2.3 adicionado ao pubspec.yaml.
  • Implementação: Em lib/services/window_service.dart:
    • Registrar Ctrl+Alt+C (ou Cmd+Alt+C no macOS) via registerGlobalHotkey().
    • Handler faz toggle de show() / hide().
  • Settings: Adicionar opção na aba Settings para customizar/desativar o atalho.

Fase 2: Tray Overflow Logic

  • Lógica: Em lib/services/tray_service.dart:
    • Implementar lógica para TrayDisplayMode.smartOverflow (All Separate vs All Unified based on threshold).
    • Implementar lógica para TrayDisplayMode.smartCollapse (First N separate, rest in Unified menu).
    • Se plugins.length > threshold, renderizar apenas 1 ícone genérico na tray (smartOverflow behavior).
    • Renderizar o menu de contexto contendo submenus para cada plugin ativo.
  • Menu Builder: Refatorar a construção do menu para suportar aninhamento dinâmico (Plugin A -> [Output, Actions]).

Fase 3: Window State Persistence ✅

  • Persistência: Em lib/services/window_service.dart:
    • Salvar Rect (posição e tamanho) e estado maximizado no shared_preferences ao fechar/ocultar/blur/maximize.
    • Restaurar Rect e estado maximizado ao iniciar o app (evitar que abra sempre no centro ou tamanho default).
    • Adicionar testes completos para persistência e restauração de estado.

🌐 Epic v1.4.0: API & Marketplace Completion

Objetivo: Preencher as lacunas nos comandos CLI e tornar o Marketplace funcional.

Fase 1: CLI Gaps

  • Geolocation: Implementado em lib/cli/commands/location_command.dart (LocationCommand).
    • IP geolocation via ipapi.co com fallback ip-api.com (sem dependência de geolocator/Flutter).
    • Geocoding (endereço -> coordenadas) via Nominatim/OpenStreetMap.
    • Reverse geocoding (coordenadas -> endereço) via Nominatim/OpenStreetMap.
    • Suporte a --json e --xml output.
  • QR Code: Implementado em lib/cli/commands/qr_command.dart (QrCommand).
    • Gera QR code em ASCII (Unicode blocks) para terminal.
    • Gera PNG base64 com flag --image.
    • Tamanho customizável via --size. Suporte a JSON/XML output.
  • Screenshot: API multiplataforma implementada em lib/core/api/utils_api.dart.
    • Linux: gnome-screenshot, scrot, spectacle (fallback chain).
    • Windows: PowerShell snippet para captura.
    • macOS: screencapture.
    • Expor como comando CLI (crossbar screenshot [path] [--clipboard]).

Fase 2: Marketplace Engine

  • GitHub API: Em lib/services/marketplace_service.dart:
    • Implementar busca real usando api.github.com/repos/{owner}/{repo}/contents/plugins.
    • Implementar cache de resultados para evitar rate limiting.
  • Instalação: Melhorar InstallCommand:
    • Clonar/Baixar plugin.
    • Validar integridade do arquivo.
    • Copiar para ~/.crossbar/plugins.
    • Executar chmod +x automaticamente.

🧩 Epic v1.8.1: Plugin Display Titles (Concluído)

Objetivo: Permitir título customizado por usuário com fallback automático para o nome padrão (UI e widgets).

  • Adicionar override de título salvo por usuário e propagar para UI/Widgets. (Commit hash: 969c394)

🔧 Epic v1.9.1: Code Quality & Robustness

Objetivo: Resolver dívidas técnicas identificadas no code review dos commits 32faafb..73d8515, focando em prevenção de memory leaks, robustez de recursos e cobertura de testes.

Context: Code review identificou áreas críticas que precisam de melhorias para garantir estabilidade em execuções longas e edge cases.

Fase 1: Resource Management (Alta Prioridade)

  • LRU Cache para _webCache: Em packages/crossbar_core/lib/src/core/lua_runner.dart:

    • Implementar limite de tamanho para Map<String, dynamic> _webCache
    • Adicionar estratégia LRU (Least Recently Used) ou limitar a 100 entradas
    • Adicionar métrica de hit/miss rate para monitoramento
    • Teste: Validar que cache não cresce indefinidamente após 500+ requests
  • Rotação de Logs Android: Em android/app/src/main/kotlin/com/verseles/crossbar/WidgetLogStore.kt:

    • Limite e FIFO já implementados (MAX_LINES = 200)
    • clear() já existe
    • Expor contador de logs descartados na UI de debug
    • Teste: Verificar que logs não excedem limite após 1000+ entradas
  • Empty Discovery Guard Documentation: Em lib/core/plugin_manager.dart:

    • Documentar lógica do _emptyDiscoveryStreak >= 2 com comentário inline
    • Considerar tornar threshold configurável via SettingsService
    • Teste: Validar comportamento em cenário "diretório realmente vazio"

Fase 2: Test Coverage Expansion (Média Prioridade)

  • Output Parser Edge Cases: Em test/unit/core/output_parser_test.dart:

    • Adicionar teste: Strings com pipes escapados (text | inner=pipe\|here)
    • Adicionar teste: Atributos multi-valor com quotes (bash="/bin/sh -c 'echo test'")
    • Adicionar teste: Atributos com espaços e caracteres especiais
    • Adicionar teste: Parsing de atributos vazios ou malformados
    • Target: Aumentar coverage de output_parser.dart para 99%+
  • Widget Tests para Plugins Tab: Criar test/widget/tabs/plugins_tab_test.dart:

    • Testar filtro "Enabled only" com lista mista de plugins
    • Testar ordenação por nome, interval, status
    • Testar busca/search functionality
    • Testar ações de enable/disable via UI
    • Target: Aumentar coverage de plugins_tab.dart de 10% para 60%+
  • Integration Test: Web Cache Persistence: Criar test/integration/web_cache_persistence_test.dart:

    • Validar que cache sobrevive a restart do app
    • Validar estratégia stale-while-revalidate em caso de erro de rede
    • Validar limpeza de cache obsoleto (>7 dias)

Fase 3: Code Organization & Maintainability (Baixa Prioridade)

  • Mover customTitleKey para Core: Em packages/crossbar_core/lib/src/models/plugin_config.dart:

    • Mover constante customTitleKey de PluginConfigService para PluginConfig
    • Adicionar documentação sobre convenção de chaves reservadas (prefixo _crossbar_)
    • Atualizar referências em plugin_config_service.dart
  • Avaliar Compressão de Cache: Em packages/crossbar_core/lib/src/core/lua_runner.dart:

    • Medir tamanho médio de cache em disco após 1 semana de uso
    • Se > 10MB, implementar compressão gzip para arquivos .json do cache
    • Adicionar métrica de espaço em disco salvo na UI de debug
  • Refactor: Widget Log Storage Abstraction: Em lib/services/widget_log_store.dart:

    • Criar interface LogStore com implementações MemoryLogStore e FileLogStore
    • Permitir switch entre in-memory (rápido) e persistente (diagnóstico)
    • Adicionar toggle na UI de Settings

Success Metrics (Definition of Done)

  • ✅ Zero memory leaks detectados em execução de 24h+ (Android Profiler)
  • ✅ Coverage geral aumentado para 42%+ (atualmente 40.7%)
  • ✅ Todos os testes de edge cases do output_parser passando
  • ✅ Widget tests para plugins_tab.dart implementados
  • ✅ Documentação inline adicionada para lógicas complexas

🧪 Estratégia de Qualidade

Para cada Epic, a seguinte "Definition of Done" deve ser respeitada:

  1. Código: Implementado seguindo flutter_lints.
  2. Testes Unitários: Classes de lógica (Services, ViewModels) com >90% coverage.
  3. Testes de Integração: Pelo menos 1 teste end-to-end para o fluxo crítico (ex: Salvar config -> Executar Plugin -> Verificar Output).
  4. Multi-plataforma: Verificar se a implementação não quebra o build em Linux/Android (CI matrix).

Status Atual de Testes

Coverage atual: 44.3% (meta: 35%)

Arquivos com Boa Cobertura (>70%)

  • output_parser.dart - 97.5%
  • refresh_service.dart - 96.5%
  • plugin_output.dart - 96.6%
  • cli_handler.dart - 95.3%
  • lua_runner.dart - 90.1%
  • plugin_config.dart - 85.3%
  • plugin_config_service.dart - 87.5%
  • script_runner.dart - 80.3%
  • plugin_manager.dart - 77.2%
  • scheduler_service.dart - 75.0%
  • declarative_runner.dart - 71.0%
  • logger_service.dart - 70.1%

Arquivos que Precisam de Mais Testes (<50%)

  • plugins_tab.dart - 10.0%
  • marketplace_service.dart - 21.9%
  • android_native_bridge.dart - 7.3%
  • utils_api.dart - 2.7%
  • Comandos CLI de hardware (audio, bluetooth, screen, etc.)

Próximas Melhorias de Testes

  • Refatorar scheduler_service_test.dart para usar classe real
  • Adicionar testes de widget/UI para plugins_tab.dart (ver Epic v1.9.1)
  • Adicionar edge cases para output_parser.dart (ver Epic v1.9.1)
  • Excluir arquivos l10n/* do cálculo de coverage (gerados automaticamente)

Nota: Melhorias detalhadas de testes estão documentadas no Epic v1.9.1: Code Quality & Robustness.


🎨 Epic v1.10.0: Tray Icon Standardization

Objetivo: Padronizar ícones de tray (bandeja do sistema) para funcionar corretamente em todas as plataformas: Linux, macOS, Windows e Android.

Status: 🟢 Fase 1 Concluída

Documento Detalhado: ROADMAP.feat013-tray-icons.md - contém pesquisa completa, especificações técnicas e plano de implementação.

Resumo das Fases

Fase 1: Correções Imediatas ✅

  • Linux - Reaplicar ícone ao trocar tema: Corrigido _onThemeChanged() para chamar setIcon() após recalcular path via novo método _updateIconForTheme()
  • Linux - gsettings monitor: Adicionado gsettings monitor org.gnome.desktop.interface color-scheme para detecção confiável de mudança de tema no GNOME (o callback onPlatformBrightnessChanged do Flutter não dispara no Linux)
  • Android - Monochrome Icon: Adicionado adaptive_icon_monochrome no pubspec.yaml + geração automática no Makefile para Material You (Android 13+)
  • Android - Notification Small Icon: Geração de ic_stat_crossbar.png monocromático (branco+transparente) em 5 densidades + referência em notification_service.dart para status bar
  • Makefile - dart build cli: Migrado compilação do tray daemon de dart compile exe para dart build cli (compatibilidade com build hooks do Dart 3.10+)

Fase 2: Melhorias Nativas 🟡

  • Linux - Freedesktop IconName: Migrar para ícone simbólico SVG que respeita tema do shell
  • macOS - Template Image: Validar/corrigir isTemplate: true para adaptação automática
  • Windows - Detecção de Tema: (Opcional) Ler registry para trocar ícone conforme tema

Fase 3: Widgets Mobile 🔵

  • Android Widgets - ImageView: Migrar de TextView para ImageView com tint dinâmico
  • iOS Widgets - SF Symbols: Suporte a prefixo sf: para ícones nativos

📱 Epic v1.13.0: Mobile Notifications & Widget Menus (ADR-015)

Objetivo: Tornar menu items de plugins acessíveis no mobile via widgets e notificações configuráveis.

Status: 🟢 Concluído

Fase 1: Settings Mobile — Seção Notifications ✅

  • NotificationStyle enum: Adicionado em SettingsService com valores combined, individual, both e persistência via SharedPreferences
  • Settings UI: Seção "System Tray" substituída por "Notifications" no mobile (Android/iOS) com dialog de estilo. Toggle "Keep on Background" movido de Behavior para Notifications no mobile. Desktop mantém System Tray inalterado.
  • i18n: Chaves adicionadas em app_en.arb e app_pt.arb (notificationStyle, notificationStyleCombined, etc.)

Fase 2: Widget Menu Button + WidgetMenuActivity ✅

  • ic_more_vert.xml: Vector drawable (3 pontos verticais, branco) para botão de menu
  • Layouts atualizados: Botão menu adicionado em small (end|bottom), medium (stacked vertical com edit), large (20dp por plugin row)
  • WidgetMenuActivity.kt: Activity Kotlin pura, dialog-themed, UI programática com bottom-sheet, dark mode, submenus inline, href abre browser, bash desabilitado
  • CrossbarWidgetBase.kt: hasMenuItems() verifica menu, setupMenuClickHandler() configura PendingIntent com offsets diferenciados
  • AndroidManifest.xml: WidgetMenuActivity registrada

Fase 3: Notificações Combinadas + Individuais ✅

  • NotificationService: showCombinedNotification() (InboxStyle, até 6 linhas) e showIndividualNotification() (BigTextStyle com menu items expandidos)
  • SchedulerService: Integrado com NotificationStyle — chama método apropriado após cada output de plugin
  • Grouping: Usa setGroup("crossbar_plugins_group") para agrupamento no Android 7+
  • IDs estáveis: pluginId.hashCode para atualização sem duplicação