← Back to Blog
AI/ML2026-05-05·33 min read

I Built a Slack Bridge for Local Codex Sessions So I Could Leave My Desk

By Duncan Brown

I Built a Slack Bridge for Local Codex Sessions So I Could Leave My Desk

Current Situation Analysis

Local Codex CLI sessions provide powerful, deterministic agent execution but inherently tether the developer to the terminal. This creates a critical workflow bottleneck: stepping away from the desk to run errands, attend meetings, or exercise breaks session momentum and forces either constant presence or premature termination. Cloud-based Codex alternatives fail to align with local-first workflows, introducing unnecessary state abstraction, network latency, and platform overhead that disrupt tight CLI integration. Traditional terminal monitoring also lacks remote control surfaces, and attempting to mirror high-volume intermediate output to external channels degrades readability and obscures critical signals. Without a lightweight, thread-scoped bridge, developers are forced to choose between mobility and session continuity, ultimately fragmenting the development loop.

WOW Moment: Key Findings

Approach Remote Mobility Context Fidelity System Overhead Session Continuity UX/API Friction
Terminal-Only 0% 100% Low High (if present) High (requires physical presence)
Cloud Platform 100% 60% (state abstraction loss) High Medium Medium (platform constraints)
Local Slack Bridge 95% 90% (final output + prompt mirroring) Low-Medium High Low (thread-scoped, ephemeral status)

Key Findings:

  • Thread-scoped mapping preserves state alignment without platform overhead
  • Final-output-only mirroring maintains high signal-to-noise ratio while enabling remote monitoring
  • Direct local rollout file parsing eliminates state synchronization delays
  • Explicit attach/resume boundaries prevent race conditions and preserve terminal ownership during in-flight turns

Core Solution

The bridge implements a thin control layer that maps local Codex sessions to Slack threads while preserving terminal-native execution. Technical implementation follows these architectural decisions:

  • Rollout File Watcher: The bridge continuously monitors local Codex rollout/session files. Upon turn completion, it extracts the final output and mirrors it to the corresponding Slack thread. If attaching mid-turn, the watcher scans the file tail to recover the original prompt alongside the final result.
  • Session-to-Thread Mapping: Each Codex session is bound to a single Slack thread. This 1:1 mapping ensures prompts, responses, attachments, and state remain aligned. Repeated attach actions are idempotent, reusing the existing thread rather than spawning competing control surfaces.
  • Attach vs Resume Logic:
    • Attach: Binds Slack to an existing terminal session. The terminal retains ownership until the current turn completes; Slack receives the final output but cannot intervene mid-turn.
    • Resume: Initiates a new turn in an existing session from Slack, taking over subsequent interactions after terminal ownership releases.
  • Slack API Adaptations: Slash commands fail inside threads, so detachment relies on Block Kit buttons and plain-text commands (detach). Ephemeral responses handle status updates and error routing. The bridge explicitly filters intermediate reasoning and tool-by-tool execution to preserve thread readability.
  • Durability & Constraints: Persistence is managed via macOS launchd. Active sessions trigger caffeinate to prevent sleep, with explicit battery/power tradeoff warnings. Access is restricted to a single authorized user, scoped to private channels or DMs, and disabled by default with persistent enable/disable state across restarts.

Pitfall Guide

  1. Over-Mirroring Intermediate Output: Routing tool-by-tool execution, reasoning steps, or incremental progress to Slack degrades thread readability and floods the control surface. Best practice: Filter strictly for final turn output to maintain high signal fidelity.
  2. Ignoring Slack Thread API Limitations: Assuming slash commands or standard interactive elements work inside threads causes silent failures. Best practice: Use plain-text commands, Block Kit buttons for actions like detach, and ephemeral messages for status/error routing.
  3. Blurring Session Ownership Boundaries: Failing to distinguish between attach (binding to an in-flight terminal turn) and resume (starting a new turn) creates race conditions and conflicting control surfaces. Best practice: Enforce terminal ownership until turn completion, then explicitly hand off to Slack.
  4. Neglecting Hardware & Power Constraints: Assuming local sessions run indefinitely without accounting for macOS sleep states or battery drain leads to silent session drops. Best practice: Use launchd for process persistence and caffeinate explicitly during active sessions, with clear user warnings about power tradeoffs.
  5. Over-Abstraction via Third-Party Platforms: Introducing heavy orchestration layers or generic agent platforms breaks tight CLI integration and complicates state management. Best practice: Maintain a thin, purpose-built bridge that directly reads local rollout/session files without intermediate state servers.
  6. Weak Access & Scope Controls: Allowing unrestricted multi-user or public channel access introduces security risks, state collisions, and unauthorized session manipulation. Best practice: Restrict to single authorized users, scope to private channels/DMs, and require explicit enable/disable toggles with persistent state.

Deliverables

  • Blueprint: Local-to-Slack Session Bridge Architecture Diagram detailing rollout file watcher event loop, Slack event adapter routing, thread mapper state machine, and ownership handoff protocol.
  • Checklist: Pre-deployment verification steps including Slack app permission scopes (chat:write, channels:read, commands), launchd plist validation, caffeinate integration testing, rollout file path configuration, and single-user auth binding.
  • Configuration Templates:
    • bridge.config.yaml: Session mapping rules, output filtering thresholds, channel/DM scoping, and enable/disable persistence flags.
    • launchd.plist: macOS service definition for bridge daemon persistence, restart policies, and environment variable injection.
    • slack-manifest.json: Minimal Slack app configuration with thread-scoped interaction rules, ephemeral response routing, and button action handlers.