Skip to content

feat: support tmux -f ~/.tmux.conf when launching agent sessions #294

@jmeekhof

Description

@jmeekhof

Support tmux configuration files in agent containers

Description

Problem

User tmux configurations (prefix key, mode-keys, custom bindings) are ignored when Scion launches agent containers, even when the config file exists at ~/.tmux.conf inside the container. This affects user experience when interacting with agents via scion attach.

Current Behavior

Scion hardcodes the tmux invocation in pkg/runtime/common.go:413-415:

tmuxCmd := fmt.Sprintf(
    "tmux new-session -d -s scion -n agent %s \\; set-option -g window-size latest \\; new-window -t scion -n shell \\; select-window -t scion:agent \\; attach-session -t scion",
    cmdLine,
)

This starts tmux without the -f flag, so tmux uses its built-in defaults:

  • prefix C-b (not user's preferred C-a)
  • mode-keys emacs (not user's preferred vi)
  • No custom keybindings or settings

Expected Behavior

When a user has a tmux config file at ~/.tmux.conf (either baked into their custom image or synced via harness configs), tmux should load and use it.

Reproduction Steps

  1. Create custom Dockerfile with user's tmux config:

    FROM _________2187.dkr.ecr.us-east-1.amazonaws.com/scion/scion-base:latest
    # ... existing scion-pi setup ...
    
    USER scion
    COPY --chown=scion:scion tmux.conf /home/scion/.tmux.conf
    USER root
  2. Build and push image to ECR

  3. Start agent using custom image:

    scion start test-agent "Simple task"
  4. Attach to agent:

    scion attach test-agent
  5. Check tmux settings:

    tmux show-options -g prefix      # Shows "C-b" (default)
    tmux show-options -g mode-keys   # Shows "emacs" (default)
  6. Verify config exists:

    cat ~/.tmux.conf | grep "prefix C-a"   # Config is present

Result: Config file exists but is not loaded by tmux.


Investigation & Root Cause

1. Primary Issue: Missing -f Flag

The tmux command in pkg/runtime/common.go and pkg/runtime/k8s_runtime.go does not include -f ~/.tmux.conf:

Current:

tmux new-session -d -s scion -n agent ...

Should be:

tmux -f ~/.tmux.conf new-session -d -s scion -n agent ...

2. Attempted Workarounds

Workaround A: Manual Reload (Doesn't Persist)

tmux source-file ~/.tmux.conf
  • ✅ Works temporarily
  • ❌ Must be run manually after attaching
  • ❌ Doesn't apply to new windows/panes created before reload

Workaround B: Post-Start Hook (Timing Issues)

Added hook at /etc/scion/hooks/post-start.d/10-reload-tmux-config:

#!/bin/bash
if command -v tmux >/dev/null 2>&1 && [ -f "$HOME/.tmux.conf" ]; then
    tmux source-file "$HOME/.tmux.conf" 2>/dev/null || true
fi

Result:

  • ✅ Hook executes (confirmed in logs: Running post-start hooks...)
  • ❌ Config not successfully reloaded
  • Root cause: Hook runs too early (before tmux fully initializes) or in wrong environment (can't access tmux socket)

Workaround C: Harness Config Home Files (Doesn't Work in Hub Mode)

Placing config in ~/.scion/harness-configs/pi-sonnet/home/.tmux.conf:

3. Related Issues

This issue is related to:


Proposed Solutions

Solution 1: Add -f ~/.tmux.conf Flag (Preferred)

Modify pkg/runtime/common.go line 413:

tmuxCmd := fmt.Sprintf(
-   "tmux new-session -d -s scion -n agent %s \\; ...",
+   "tmux -f ~/.tmux.conf new-session -d -s scion -n agent %s \\; ...",
    cmdLine,
)

Also update pkg/runtime/k8s_runtime.go with same change.

Benefits:

  • ✅ Simple one-line change
  • ✅ Respects user preferences
  • ✅ Standard tmux behavior
  • ✅ No breaking changes (if file missing, tmux falls back to defaults)

Fallback safety: If ~/.tmux.conf doesn't exist, tmux silently uses defaults.

Solution 2: Make Hook Timing Reliable (Alternative)

Document how to make post-start hooks work reliably with tmux:

  • Add $HOME environment to hook execution
  • Ensure hook runs after tmux socket is available
  • Add retry logic in hook system

Benefits:

  • ✅ More flexible (works for other config files)
  • ❌ More complex
  • ❌ Timing still tricky

Solution 3: Configuration Option (Most Flexible)

Add harness config option:

# ~/.scion/harness-configs/pi-sonnet/config.yaml
tmux:
  config_file: ~/.tmux.conf  # or null to use defaults
  options:
    - "set-option -g prefix C-a"
    - "setw -g mode-keys vi"

Benefits:

  • ✅ Most flexible
  • ✅ Doesn't require baking config into image
  • ❌ Most complex to implement
  • ❌ Yet another config layer

Impact & Use Cases

Who This Affects

Current workaround for affected users: Use --no-hub mode, which loses Hub features (secrets management, web UI, broker coordination).

Affected users:

  1. Power users with muscle memory for custom tmux keybindings
  2. Teams standardizing on specific tmux configs across agents
  3. Users with accessibility needs requiring specific keybindings
  4. Vim users who expect vi-mode in copy/paste operations

Real-World Scenario

User has Ctrl-a prefix and vi-mode in their local tmux. When they scion attach to debug an agent, they:

  • Press Ctrl-a d to detach → nothing happens (prefix is still Ctrl-b)
  • Enter copy mode → emacs keys, not vi keys
  • Repeatedly hit wrong keybindings, slowing down debugging

Testing

Test Case 1: Config File Present

# In Dockerfile
COPY tmux.conf /home/scion/.tmux.conf

# After agent starts
$ tmux show-options -g prefix
prefix C-a  # ✅ Should show user's custom prefix

$ tmux show-options -g mode-keys
mode-keys vi  # ✅ Should show user's custom mode

Test Case 2: No Config File

# Don't add tmux.conf to image

# After agent starts  
$ tmux show-options -g prefix
prefix C-b  # ✅ Should fall back to defaults

$ tmux show-options -g mode-keys
mode-keys emacs  # ✅ Should fall back to defaults

Test Case 3: Invalid Config

# Add broken tmux.conf
COPY broken-tmux.conf /home/scion/.tmux.conf

# tmux should fail gracefully with error message
# Container should still start (don't fail hard on bad config)

Implementation Notes

Files to Modify

  1. pkg/runtime/common.go (line ~413):

    tmuxCmd := fmt.Sprintf(
        "tmux -f ~/.tmux.conf new-session -d -s scion -n agent %s \\; ...",
        cmdLine,
    )
  2. pkg/runtime/k8s_runtime.go (similar location):
    Same change for Kubernetes runtime

  3. Tests to update:

    • pkg/runtime/common_test.go - update expected tmux commands
    • pkg/runtime/k8s_runtime_tmux_test.go - same

Backward Compatibility

No breaking changes: If ~/.tmux.conf doesn't exist, tmux silently uses built-in defaults (standard tmux behavior).

Documentation to Update

  • Harness configuration docs: mention users can bake tmux.conf into images
  • Container build docs: example of adding custom tmux config
  • Troubleshooting: note about -f flag for debugging tmux issues

Environment

  • Scion version: main branch (commit d20a238+)
  • Runtime: Apple container CLI
  • Harness: pi
  • OS: macOS (Apple container)
  • Image: Custom scion-pi:latest with tmux.conf baked in

Additional Context

Example Custom Config

User's ~/.tmux.conf that should be loaded:

# Prefix
unbind C-b
set -g prefix C-a
bind C-a send-prefix

# Vi mode
setw -g mode-keys vi
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection

# Splits
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

Logs Showing Hook Execution

From scion logs test-agent:

2026-06-01 18:43:37 [sciontool] [INFO] Running post-start hooks...

Hook was called but config not loaded (timing/environment issue).


Questions for Maintainers

  1. Is Solution 1 (adding -f ~/.tmux.conf) acceptable? Any concerns about the change?

  2. Should we also support a TMUX_CONF env var override?

    TMUX_CONF=/custom/path/tmux.conf scion start ...
  3. Post-start hooks: What's the intended use case? Our hook executes but can't reliably interact with tmux. Is this expected?

  4. Hub mode vs local mode: Related to Hub-dispatched agents do not apply harness config or template volumes #101 - is there a roadmap for making harness home files work in Hub mode, or should users bake configs into images?


Workaround (Until Fixed)

For users who need custom tmux configs NOW:

Option A: Use --no-hub Mode

scion start --no-hub agent-name "task"
  • ✅ Harness configs work
  • ❌ Lose Hub features (secrets, web UI, coordination)

Option B: Manually Reload After Attach

scion attach agent-name
# Then inside container:
tmux source-file ~/.tmux.conf
  • ✅ Works immediately
  • ❌ Must do every time
  • ❌ Doesn't affect windows created before reload

Option C: Alias in Shell RC

Add to image's ~/.zshrc or ~/.bashrc:

alias ta='tmux source-file ~/.tmux.conf && echo "Tmux config reloaded"'

Then run ta after attaching.


References


Would appreciate any guidance on the preferred solution! Happy to submit a PR for Solution 1 if that direction makes sense.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions