Skip to content

v0.1.0 — macOS menu-bar wrapper

Choose a tag to compare

@gregoryoviedo gregoryoviedo released this 20 Aug 01:43
· 60 commits to main since this release

✨ Novedades

  • App nativa de macOS (OpenCodeRemote.app, arm64, ~12 MB)
    • Icono en la barra de menús con toggle estilo Bluetooth.
    • Formulario de Settings en SwiftUI (WORKSPACE_ROOT, token de Telegram, chat ID, puerto y bin de OpenCode, autostart, TELEGRAM_API_ROOT, TELEGRAM_PROXY_URL).
    • Auto-inicio al login vía SMAppService.mainApp.
    • Logs accesibles desde el menú (~/Library/Logs/OpenCodeRemote/bot.log).
    • Build reproducible con make app (XcodeGen + xcodebuild + codesign ad-hoc).
  • Binario Go endurecido:
    • TELEGRAM_API_ROOT y TELEGRAM_PROXY_URL ahora se leen del entorno o del .env, y el wrapper los reenvía al proceso hijo en proc.environment (antes se quedaban en el .env y nunca llegaban al bot).
    • Respuestas JSON del cliente OpenCode capadas a 32 MB con io.LimitReader para evitar OOM ante un server rebelde.
    • domain/errors.go ahora expone sentinels (ErrUnauthorizedNavigation, ErrServerNotRunning, ErrSessionRequired, ErrProjectRequired, ErrWorkspaceNotConfigured) para que adapters y callers puedan hacer errors.Is.
    • Renombrado usecase.BotHandler a usecase.Handler para eliminar la colisión con el port domain.BotHandler.
    • Eliminado código muerto: domain.AppConfig, domain.OpenCodeEvent, OpenCodeClient.SubscribeEvents y el pipeline SSE completo (unas 80 líneas sin caller).
  • Wrapper Swift más robusto:
    • TELEGRAM_API_ROOT y TELEGRAM_PROXY_URL se exportan al binario Go en proc.environment (bug crítico corregido).
    • StatusBarController ya no leakea el observer de NotificationCenter (se desuscribe en deinit).
    • LoginItemManager.isInstalledInApplications exige match exacto de /Applications/ o ~/Applications/ (antes matcheaba falsos positivos como ~/Downloads/.../Applications/).
    • El "Tiempo activo" del popover refresca cada segundo con un Timer.publish(every: 1).
    • applyPaste(.port) ahora muestra feedback en lugar de descartar silenciosamente valores inválidos.
    • savedAt se limpia cuando un guardado falla.
    • Quitada la duplicación stateSubject + onStateChange en AppDelegate; queda una sola vía de notificación.
  • Documentación:
    • README.md: sección nueva App nativa de macOS con build, instalación, Gatekeeper, auto-inicio, toggle y prerequisitos (Xcode, XcodeGen, Go, Pillow).
    • docs/DESIGN.md: nueva sección Why two different architectures in one project explicando por qué Go usa hexagonal y Swift usa MVVM, y por qué la frontera entre los dos runtimes es un contrato de proceso (.env + Process), no código compartido.
    • docs/PRODUCT.md: el wrapper Swift queda registrado en Implemented; Out of scope se ajusta (sigue siendo single-user / single-chat; el wrapper no toca la red).

🐛 Bug fix crítico

TELEGRAM_API_ROOT y TELEGRAM_PROXY_URL configurados en Settings del wrapper ahora sí llegan al proceso Go (antes se escribían al .env pero el bot los leía con os.Getenv, no del .env). Si usás un mirror de la API o un proxy corporativo, esto te afecta directamente.

📦 Artefactos

  • OpenCodeRemote.app — bundle macOS arm64 ad-hoc firmado, ~12 MB.
    Embeido: binario remote-bot arm64 (~10 MB) generado con go build -trimpath -ldflags="-s -w".

🔧 Instalación

# 1. Mover a /Applications
cp -R OpenCodeRemote.app /Applications/

# 2. Quitar marca de Gatekeeper (no tiene Developer ID)
xattr -dr com.apple.quarantine /Applications/OpenCodeRemote.app

# 3. Abrir
open /Applications/OpenCodeRemote.app

Primera vez: abrir Settings…, llenar los 3 campos obligatorios, Guardar. A partir de ahí el toggle funciona.

🧪 Uso sin wrapper (CLI puro)

go build -o remote-bot ./cmd/remote-bot
cp .env.example .env
$EDITOR .env
./remote-bot

⚠️ Notas

  • App ad-hoc firmada. macOS la bloquea en la primera apertura; click-derecho → Abrir, o xattr -dr com.apple.quarantine /Applications/OpenCodeRemote.app.
  • arm64-only (sin slice Intel por ahora).
  • Sandbox deshabilitado en el wrapper porque hace spawn de un binario externo y escribe en ~/Library/....