Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions registry/coder/modules/goose/README.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also move the script to a run.sh? It could also be a separate PR effort. Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'll go ahead split it into the run script shouldn't be too hard

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Run the [Goose](https://block.github.io/goose/) agent in your workspace to gener
```tf
module "goose" {
source = "registry.coder.com/coder/goose/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
folder = "/home/coder"
install_goose = true
Expand All @@ -24,14 +24,14 @@ module "goose" {

## Prerequisites

- `screen` must be installed in your workspace to run Goose in the background
- `screen` or `tmux` must be installed in your workspace to run Goose in the background
- You must add the [Coder Login](https://registry.coder.com/modules/coder-login) module to your template

The `codercom/oss-dogfood:latest` container image can be used for testing on container-based workspaces.

## Examples

Your workspace must have `screen` installed to use this.
Your workspace must have `screen` or `tmux` installed to use the background session functionality.

### Run in the background and report tasks (Experimental)

Expand Down Expand Up @@ -90,7 +90,7 @@ resource "coder_agent" "main" {
module "goose" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/goose/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
folder = "/home/coder"
install_goose = true
Expand All @@ -99,8 +99,12 @@ module "goose" {
# Enable experimental features
experiment_report_tasks = true

# Run Goose in the background
# Run Goose in the background with screen (pick one: screen or tmux)
Copy link
Member

@Parkreiner Parkreiner May 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a data modeling standpoint, would we want to get rid of the screen and TMUX variables, and have a single string variable that has the value of "tmux" or "screen" (using a validation field to make sure the value is one of those two)?

I don't know what that would mean for how we've handled versions up until now, since that would be a breaking change, but it feels janky to me that a user can accidentally set both of them, even though only one should be set at a time. I know the script checks for whether they're both set, but for user clarity, it feels like the data should be modeled as being more mutually exclusive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly that's a super valid point that would be a much simpler solution

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the variables for now.
We can make this change for all modules at some time and bump to 2.0.0

experiment_use_screen = true
# experiment_use_tmux = true # Alternative: use tmux instead of screen

# Optional: customize the session name (defaults to "goose")
# session_name = "goose-session"

# Avoid configuring Goose manually
experiment_auto_configure = true
Expand Down Expand Up @@ -143,12 +147,12 @@ Note: The indentation in the heredoc is preserved, so you can write the YAML nat

## Run standalone

Run Goose as a standalone app in your workspace. This will install Goose and run it directly without using screen or any task reporting to the Coder UI.
Run Goose as a standalone app in your workspace. This will install Goose and run it directly without using screen or tmux, and without any task reporting to the Coder UI.

```tf
module "goose" {
source = "registry.coder.com/coder/goose/coder"
version = "1.1.1"
version = "1.2.0"
agent_id = coder_agent.example.id
folder = "/home/coder"
install_goose = true
Expand Down
101 changes: 73 additions & 28 deletions registry/coder/modules/goose/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ variable "experiment_use_screen" {
default = false
}

variable "experiment_use_tmux" {
type = bool
description = "Whether to use tmux instead of screen for running Goose in the background."
default = false
}

variable "session_name" {
type = string
description = "Name for the persistent session (screen or tmux)"
default = "goose"
}

variable "experiment_report_tasks" {
type = bool
description = "Whether to enable task reporting."
Expand Down Expand Up @@ -187,8 +199,52 @@ EOL
mkdir -p "$HOME/.config/goose"
echo "$GOOSE_SYSTEM_PROMPT" > "$HOME/.config/goose/.goosehints"

# Run with screen if enabled
if [ "${var.experiment_use_screen}" = "true" ]; then
# Handle terminal multiplexer selection (tmux or screen)
if [ "${var.experiment_use_tmux}" = "true" ] && [ "${var.experiment_use_screen}" = "true" ]; then
echo "Error: Both experiment_use_tmux and experiment_use_screen cannot be true simultaneously."
echo "Please set only one of them to true."
exit 1
fi

# Determine goose command
if command_exists goose; then
GOOSE_CMD=goose
elif [ -f "$HOME/.local/bin/goose" ]; then
GOOSE_CMD="$HOME/.local/bin/goose"
else
echo "Error: Goose is not installed. Please enable install_goose or install it manually."
exit 1
fi

# Run with tmux if enabled
if [ "${var.experiment_use_tmux}" = "true" ]; then
echo "Running Goose in the background with tmux..."

# Check if tmux is installed
if ! command_exists tmux; then
echo "Error: tmux is not installed. Please install tmux manually."
exit 1
fi

touch "$HOME/.goose.log"

export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# Configure tmux for shared sessions
if [ ! -f "$HOME/.tmux.conf" ]; then
echo "Creating ~/.tmux.conf with shared session settings..."
echo "set -g mouse on" > "$HOME/.tmux.conf"
fi

if ! grep -q "^set -g mouse on$" "$HOME/.tmux.conf"; then
echo "Adding 'set -g mouse on' to ~/.tmux.conf..."
echo "set -g mouse on" >> "$HOME/.tmux.conf"
fi

# Create a new tmux session in detached mode
tmux new-session -d -s ${var.session_name} -c ${var.folder} "\"$GOOSE_CMD\" run --text \"Review your goosehints. Every step of the way, report tasks to Coder with proper descriptions and statuses. Your task at hand: $GOOSE_TASK_PROMPT\" --interactive | tee -a \"$HOME/.goose.log\"; exec bash"
elif [ "${var.experiment_use_screen}" = "true" ]; then
echo "Running Goose in the background..."

# Check if screen is installed
Expand Down Expand Up @@ -217,31 +273,11 @@ EOL
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# Determine goose command
if command_exists goose; then
GOOSE_CMD=goose
elif [ -f "$HOME/.local/bin/goose" ]; then
GOOSE_CMD="$HOME/.local/bin/goose"
else
echo "Error: Goose is not installed. Please enable install_goose or install it manually."
exit 1
fi

screen -U -dmS goose bash -c "
screen -U -dmS ${var.session_name} bash -c "
cd ${var.folder}
\"$GOOSE_CMD\" run --text \"Review your goosehints. Every step of the way, report tasks to Coder with proper descriptions and statuses. Your task at hand: $GOOSE_TASK_PROMPT\" --interactive | tee -a \"$HOME/.goose.log\"
/bin/bash
"
else
# Check if goose is installed before running
if command_exists goose; then
GOOSE_CMD=goose
elif [ -f "$HOME/.local/bin/goose" ]; then
GOOSE_CMD="$HOME/.local/bin/goose"
else
echo "Error: Goose is not installed. Please enable install_goose or install it manually."
exit 1
fi
fi
EOT
run_on_start = true
Expand Down Expand Up @@ -270,18 +306,27 @@ resource "coder_app" "goose" {
exit 1
fi

if [ "${var.experiment_use_screen}" = "true" ]; then
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

if [ "${var.experiment_use_tmux}" = "true" ]; then
if tmux has-session -t ${var.session_name} 2>/dev/null; then
echo "Attaching to existing Goose tmux session." | tee -a "$HOME/.goose.log"
tmux attach-session -t ${var.session_name}
else
echo "Starting a new Goose tmux session." | tee -a "$HOME/.goose.log"
tmux new-session -s ${var.session_name} -c ${var.folder} "\"$GOOSE_CMD\" run --text \"Review your goosehints. Every step of the way, report tasks to Coder with proper descriptions and statuses. Your task at hand: $GOOSE_TASK_PROMPT\" --interactive | tee -a \"$HOME/.goose.log\"; exec bash"
fi
elif [ "${var.experiment_use_screen}" = "true" ]; then
# Check if session exists first
if ! screen -list | grep -q "goose"; then
if ! screen -list | grep -q "${var.session_name}"; then
echo "Error: No existing Goose session found. Please wait for the script to start it."
exit 1
fi
# Only attach to existing session
screen -xRR goose
screen -xRR ${var.session_name}
else
cd ${var.folder}
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
"$GOOSE_CMD" run --text "Review goosehints. Your task: $GOOSE_TASK_PROMPT" --interactive
fi
EOT
Expand Down