## Context

The system provides terminal access to running tool instances via WebSocket, spawning a `bash -il` shell inside the container using `docker exec`. Currently, there is no way to customize what runs when a new terminal session starts.

The OpenCode tool type provides a web terminal interface but lacks common productivity utilities (`tmux`, `ranger`) that developers expect.

Existing related specs:
- `tool-types-definition`: Defines the ToolType model and CRUD API
- `tool-terminal`: Defines WebSocket terminal session behavior
- `opencode-web-server`: Defines OpenCode container requirements
- `tool-config-management`: ToolConfig already has `start_command` for runtime process startup

## Goals / Non-Goals

**Goals:**
- Allow tool type authors to specify a `startup_command` that executes for every new terminal session
- Execute the startup command before the interactive shell in terminal sessions
- Make `tmux` and `ranger` available in OpenCode containers
- Support creating and editing `startup_command` via the Tool Workshop UI

**Non-Goals:**
- Per-instance startup command overrides (out of scope; can be added later)
- Startup commands for web interface tools (only terminal sessions)
- Changing the tool's main process start command (already handled by `tool-config-management`)

## Decisions

### 1. Add `startup_command` to ToolType model
**Rationale**: The startup command is a property of the tool type itself, defining the environment/setup expected for that tool. This aligns with how tool types define other container behavior.
**Alternative considered**: Adding it to ToolConfig. Rejected because ToolConfig is per-user configuration, and startup behavior is more of a tool type contract.

### 2. Execute startup command via bash -c before interactive shell
**Rationale**: The simplest approach that works with any shell. We'll construct the command as: `bash -c "<startup_command>" && bash -il` or use a here-document approach.
**Alternative considered**: Writing a startup script to the container filesystem. Rejected because it requires container filesystem modification and doesn't work well with read-only containers.

### 3. Pass startup_command through TerminalSession.start()
**Rationale**: The TerminalSession is responsible for spawning the shell, so it needs the command. The terminal_manager will fetch the tool type's startup_command from the database when creating a session.
**Implementation**: Modify `TerminalManager.get_or_create_session()` to accept an optional `startup_command` parameter. The terminal API endpoint will fetch the tool type via the instance and pass it.

### 4. Install tmux and ranger via compose template
**Rationale**: OpenCode is defined as a Docker Compose tool type. The most maintainable approach is to install utilities via the container's package manager in the compose template (e.g., via a custom Dockerfile or init commands).
**Alternative considered**: Building a custom OpenCode Docker image. Rejected because it adds operational complexity; installing via compose is sufficient for now.

## Risks / Trade-offs

- [Risk] Long-running startup commands could delay terminal availability → Mitigation: Document that startup commands should be fast; consider adding a timeout in a future iteration
- [Risk] Startup command failures could prevent shell access → Mitigation: Use `&&` to chain; if the startup command fails, the shell still starts (use `;` or `|| true` pattern). Actually, use: `bash -c "<cmd>" || true; exec bash -il`
- [Risk] UI clutter from additional field in Tool Workshop → Mitigation: Show `startup_command` only for terminal interface types

## Migration Plan

1. Database migration: Add `startup_command` text column to `tool_types` table
2. Backend: Update ToolType model, Pydantic schemas, API endpoints
3. Backend: Update TerminalSession to accept and execute startup_command
4. Backend: Update terminal WebSocket endpoint to fetch and pass startup_command
5. Frontend: Add `startup_command` field to Tool Workshop form
6. Infrastructure: Update OpenCode compose template to install tmux and ranger
7. Tests: Update existing tests and add new ones for startup command behavior

## Open Questions

None at this time.
