diff --git a/.icons/claude.svg b/.icons/claude.svg
new file mode 100644
index 00000000..998fb0d5
--- /dev/null
+++ b/.icons/claude.svg
@@ -0,0 +1,4 @@
+
diff --git a/.icons/goose.svg b/.icons/goose.svg
new file mode 100644
index 00000000..cbbe8419
--- /dev/null
+++ b/.icons/goose.svg
@@ -0,0 +1,4 @@
+
diff --git a/claude-code/README.md b/claude-code/README.md
new file mode 100644
index 00000000..2422f174
--- /dev/null
+++ b/claude-code/README.md
@@ -0,0 +1,112 @@
+---
+display_name: Claude Code
+description: Run Claude Code in your workspace
+icon: ../.icons/claude.svg
+maintainer_github: coder
+verified: true
+tags: [agent, claude-code]
+---
+
+# Claude Code
+
+Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview) agent in your workspace to generate code and perform tasks.
+
+```tf
+module "claude-code" {
+ source = "registry.coder.com/modules/claude-code/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+ folder = "/home/coder"
+ install_claude_code = true
+ claude_code_version = "latest"
+}
+```
+
+### Prerequisites
+
+- Node.js and npm must be installed in your workspace to install Claude Code
+- `screen` must be installed in your workspace to run Claude Code 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
+
+### Run in the background and report tasks (Experimental)
+
+> This functionality is in early access and subject to change. Do not run in
+> production as it is unstable. Instead, deploy these changes into a demo or
+> staging environment.
+>
+> Join our [Discord channel](https://discord.gg/coder) or
+> [contact us](https://coder.com/contact) to get help or share feedback.
+
+Your workspace must have `screen` installed to use this.
+
+```tf
+variable "anthropic_api_key" {
+ type = string
+ description = "The Anthropic API key"
+ sensitive = true
+}
+
+module "coder-login" {
+ count = data.coder_workspace.me.start_count
+ source = "registry.coder.com/modules/coder-login/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+}
+
+data "coder_parameter" "ai_prompt" {
+ type = "string"
+ name = "AI Prompt"
+ default = ""
+ description = "Write a prompt for Claude Code"
+ mutable = true
+}
+
+# Set the prompt and system prompt for Claude Code via environment variables
+resource "coder_agent" "main" {
+ # ...
+ env = {
+ CODER_MCP_CLAUDE_API_KEY = var.anthropic_api_key # or use a coder_parameter
+ CODER_MCP_CLAUDE_TASK_PROMPT = data.coder_parameter.ai_prompt.value
+ CODER_MCP_APP_STATUS_SLUG = "claude-code"
+ CODER_MCP_CLAUDE_SYSTEM_PROMPT = <<-EOT
+ You are a helpful assistant that can help with code.
+ EOT
+ }
+}
+
+module "claude-code" {
+ count = data.coder_workspace.me.start_count
+ source = "registry.coder.com/modules/claude-code/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+ folder = "/home/coder"
+ install_claude_code = true
+ claude_code_version = "0.2.57"
+
+ # Enable experimental features
+ experiment_use_screen = true
+ experiment_report_tasks = true
+}
+```
+
+## Run standalone
+
+Run Claude Code as a standalone app in your workspace. This will install Claude Code and run it directly without using screen or any task reporting to the Coder UI.
+
+```tf
+module "claude-code" {
+ source = "registry.coder.com/modules/claude-code/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+ folder = "/home/coder"
+ install_claude_code = true
+ claude_code_version = "latest"
+
+ # Icon is not available in Coder v2.20 and below, so we'll use a custom icon URL
+ icon = "https://registry.npmmirror.com/@lobehub/icons-static-png/1.24.0/files/dark/claude-color.png"
+}
+```
diff --git a/claude-code/main.tf b/claude-code/main.tf
new file mode 100644
index 00000000..349af17f
--- /dev/null
+++ b/claude-code/main.tf
@@ -0,0 +1,170 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ coder = {
+ source = "coder/coder"
+ version = ">= 0.17"
+ }
+ }
+}
+
+variable "agent_id" {
+ type = string
+ description = "The ID of a Coder agent."
+}
+
+data "coder_workspace" "me" {}
+
+data "coder_workspace_owner" "me" {}
+
+variable "order" {
+ type = number
+ description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)."
+ default = null
+}
+
+variable "icon" {
+ type = string
+ description = "The icon to use for the app."
+ default = "/icon/claude.svg"
+}
+
+variable "folder" {
+ type = string
+ description = "The folder to run Claude Code in."
+ default = "/home/coder"
+}
+
+variable "install_claude_code" {
+ type = bool
+ description = "Whether to install Claude Code."
+ default = true
+}
+
+variable "claude_code_version" {
+ type = string
+ description = "The version of Claude Code to install."
+ default = "latest"
+}
+
+variable "experiment_use_screen" {
+ type = bool
+ description = "Whether to use screen for running Claude Code in the background."
+ default = false
+}
+
+variable "experiment_report_tasks" {
+ type = bool
+ description = "Whether to enable task reporting."
+ default = false
+}
+
+# Install and Initialize Claude Code
+resource "coder_script" "claude_code" {
+ agent_id = var.agent_id
+ display_name = "Claude Code"
+ icon = var.icon
+ script = <<-EOT
+ #!/bin/bash
+ set -e
+
+ # Function to check if a command exists
+ command_exists() {
+ command -v "$1" >/dev/null 2>&1
+ }
+
+ # Install Claude Code if enabled
+ if [ "${var.install_claude_code}" = "true" ]; then
+ if ! command_exists npm; then
+ echo "Error: npm is not installed. Please install Node.js and npm first."
+ exit 1
+ fi
+ echo "Installing Claude Code..."
+ npm install -g @anthropic-ai/claude-code@${var.claude_code_version}
+ fi
+
+ if [ "${var.experiment_report_tasks}" = "true" ]; then
+ echo "Configuring Claude Code to report tasks via Coder MCP..."
+ coder exp mcp configure claude-code ${var.folder}
+ fi
+
+ # Run with screen if enabled
+ if [ "${var.experiment_use_screen}" = "true" ]; then
+ echo "Running Claude Code in the background..."
+
+ # Check if screen is installed
+ if ! command_exists screen; then
+ echo "Error: screen is not installed. Please install screen manually."
+ exit 1
+ fi
+
+ touch "$HOME/.claude-code.log"
+
+ # Ensure the screenrc exists
+ if [ ! -f "$HOME/.screenrc" ]; then
+ echo "Creating ~/.screenrc and adding multiuser settings..." | tee -a "$HOME/.claude-code.log"
+ echo -e "multiuser on\nacladd $(whoami)" > "$HOME/.screenrc"
+ fi
+
+ if ! grep -q "^multiuser on$" "$HOME/.screenrc"; then
+ echo "Adding 'multiuser on' to ~/.screenrc..." | tee -a "$HOME/.claude-code.log"
+ echo "multiuser on" >> "$HOME/.screenrc"
+ fi
+
+ if ! grep -q "^acladd $(whoami)$" "$HOME/.screenrc"; then
+ echo "Adding 'acladd $(whoami)' to ~/.screenrc..." | tee -a "$HOME/.claude-code.log"
+ echo "acladd $(whoami)" >> "$HOME/.screenrc"
+ fi
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+
+ screen -U -dmS claude-code bash -c '
+ cd ${var.folder}
+ claude --dangerously-skip-permissions | tee -a "$HOME/.claude-code.log"
+ exec bash
+ '
+ # Extremely hacky way to send the prompt to the screen session
+ # This will be fixed in the future, but `claude` was not sending MCP
+ # tasks when an initial prompt is provided.
+ screen -S claude-code -X stuff "$CODER_MCP_CLAUDE_TASK_PROMPT"
+ sleep 5
+ screen -S claude-code -X stuff "^M"
+ else
+ # Check if claude is installed before running
+ if ! command_exists claude; then
+ echo "Error: Claude Code is not installed. Please enable install_claude_code or install it manually."
+ exit 1
+ fi
+ fi
+ EOT
+ run_on_start = true
+}
+
+resource "coder_app" "claude_code" {
+ slug = "claude-code"
+ display_name = "Claude Code"
+ agent_id = var.agent_id
+ command = <<-EOT
+ #!/bin/bash
+ set -e
+
+ if [ "${var.experiment_use_screen}" = "true" ]; then
+ if screen -list | grep -q "claude-code"; then
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+ echo "Attaching to existing Claude Code session." | tee -a "$HOME/.claude-code.log"
+ screen -xRR claude-code
+ else
+ echo "Starting a new Claude Code session." | tee -a "$HOME/.claude-code.log"
+ screen -S claude-code bash -c 'export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; claude --dangerously-skip-permissions | tee -a "$HOME/.claude-code.log"; exec bash'
+ fi
+ else
+ cd ${var.folder}
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+ claude
+ fi
+ EOT
+ icon = var.icon
+}
diff --git a/filebrowser/README.md b/filebrowser/README.md
index 13e06577..3a0e56bd 100644
--- a/filebrowser/README.md
+++ b/filebrowser/README.md
@@ -15,7 +15,7 @@ A file browser for your workspace.
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/filebrowser/coder"
- version = "1.0.29"
+ version = "1.0.31"
agent_id = coder_agent.example.id
}
```
@@ -30,7 +30,7 @@ module "filebrowser" {
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/filebrowser/coder"
- version = "1.0.29"
+ version = "1.0.31"
agent_id = coder_agent.example.id
folder = "/home/coder/project"
}
@@ -42,7 +42,7 @@ module "filebrowser" {
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/filebrowser/coder"
- version = "1.0.29"
+ version = "1.0.31"
agent_id = coder_agent.example.id
database_path = ".config/filebrowser.db"
}
@@ -54,7 +54,7 @@ module "filebrowser" {
module "filebrowser" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/modules/filebrowser/coder"
- version = "1.0.29"
+ version = "1.0.31"
agent_id = coder_agent.example.id
agent_name = "main"
subdomain = false
diff --git a/filebrowser/main.test.ts b/filebrowser/main.test.ts
deleted file mode 100644
index 368075b2..00000000
--- a/filebrowser/main.test.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-import { describe, expect, it } from "bun:test";
-import {
- executeScriptInContainer,
- runTerraformApply,
- runTerraformInit,
- testRequiredVariables,
-} from "../test";
-
-describe("filebrowser", async () => {
- await runTerraformInit(import.meta.dir);
-
- testRequiredVariables(import.meta.dir, {
- agent_id: "foo",
- });
-
- it("fails with wrong database_path", async () => {
- const state = await runTerraformApply(import.meta.dir, {
- agent_id: "foo",
- database_path: "nofb",
- }).catch((e) => {
- if (!e.message.startsWith("\nError: Invalid value for variable")) {
- throw e;
- }
- });
- });
-
- it("runs with default", async () => {
- const state = await runTerraformApply(import.meta.dir, {
- agent_id: "foo",
- });
- const output = await executeScriptInContainer(state, "alpine");
- expect(output.exitCode).toBe(0);
- expect(output.stdout).toEqual([
- "\u001b[0;1mInstalling filebrowser ",
- "",
- "🥳 Installation complete! ",
- "",
- "👷 Starting filebrowser in background... ",
- "",
- "📂 Serving /root at http://localhost:13339 ",
- "",
- "Running 'filebrowser --noauth --root /root --port 13339 --baseurl ' ",
- "",
- "📝 Logs at /tmp/filebrowser.log",
- ]);
- });
-
- it("runs with database_path var", async () => {
- const state = await runTerraformApply(import.meta.dir, {
- agent_id: "foo",
- database_path: ".config/filebrowser.db",
- });
- const output = await executeScriptInContainer(state, "alpine");
- expect(output.exitCode).toBe(0);
- expect(output.stdout).toEqual([
- "\u001b[0;1mInstalling filebrowser ",
- "",
- "🥳 Installation complete! ",
- "",
- "👷 Starting filebrowser in background... ",
- "",
- "📂 Serving /root at http://localhost:13339 ",
- "",
- "Running 'filebrowser --noauth --root /root --port 13339 -d .config/filebrowser.db --baseurl ' ",
- "",
- "📝 Logs at /tmp/filebrowser.log",
- ]);
- });
-
- it("runs with folder var", async () => {
- const state = await runTerraformApply(import.meta.dir, {
- agent_id: "foo",
- folder: "/home/coder/project",
- });
- const output = await executeScriptInContainer(state, "alpine");
- expect(output.exitCode).toBe(0);
- expect(output.stdout).toEqual([
- "\u001b[0;1mInstalling filebrowser ",
- "",
- "🥳 Installation complete! ",
- "",
- "👷 Starting filebrowser in background... ",
- "",
- "📂 Serving /home/coder/project at http://localhost:13339 ",
- "",
- "Running 'filebrowser --noauth --root /home/coder/project --port 13339 --baseurl ' ",
- "",
- "📝 Logs at /tmp/filebrowser.log",
- ]);
- });
-
- it("runs with subdomain=false", async () => {
- const state = await runTerraformApply(import.meta.dir, {
- agent_id: "foo",
- agent_name: "main",
- subdomain: false,
- });
- const output = await executeScriptInContainer(state, "alpine");
- expect(output.exitCode).toBe(0);
- expect(output.stdout).toEqual([
- "\u001B[0;1mInstalling filebrowser ",
- "",
- "🥳 Installation complete! ",
- "",
- "👷 Starting filebrowser in background... ",
- "",
- "📂 Serving /root at http://localhost:13339 ",
- "",
- "Running 'filebrowser --noauth --root /root --port 13339 --baseurl /@default/default.main/apps/filebrowser' ",
- "",
- "📝 Logs at /tmp/filebrowser.log",
- ]);
- });
-});
diff --git a/filebrowser/run.sh b/filebrowser/run.sh
index b8927582..84810e4e 100644
--- a/filebrowser/run.sh
+++ b/filebrowser/run.sh
@@ -22,11 +22,11 @@ export FB_DATABASE="${DB_PATH}"
# Check if filebrowser db exists
if [[ ! -f "${DB_PATH}" ]]; then
- filebrowser config init 2>&1 | tee -a ${LOG_PATH}
- filebrowser users add admin "" --perm.admin=true --viewMode=mosaic 2>&1 | tee -a ${LOG_PATH}
+ filebrowser config init 2>&1 | tee -a ${LOG_PATH}
+ filebrowser users add admin "" --perm.admin=true --viewMode=mosaic 2>&1 | tee -a ${LOG_PATH}
fi
-filebrowser config set --baseurl=${SERVER_BASE_PATH} --port=${PORT} --auth.method=noauth --root=$ROOT_DIR 2>&1 | tee -a ${LOG_PATH}
+filebrowser config set --baseurl=${SERVER_BASE_PATH} --port=${PORT} --auth.method=noauth --root=$ROOT_DIR 2>&1 | tee -a ${LOG_PATH}
printf "👷 Starting filebrowser in background... \n\n"
diff --git a/goose/README.md b/goose/README.md
new file mode 100644
index 00000000..5735cb76
--- /dev/null
+++ b/goose/README.md
@@ -0,0 +1,125 @@
+---
+display_name: Goose
+description: Run Goose in your workspace
+icon: ../.icons/goose.svg
+maintainer_github: coder
+verified: true
+tags: [agent, goose]
+---
+
+# Goose
+
+Run the [Goose](https://block.github.io/goose/) agent in your workspace to generate code and perform tasks.
+
+```tf
+module "goose" {
+ source = "registry.coder.com/modules/goose/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+ folder = "/home/coder"
+ install_goose = true
+ goose_version = "v1.0.16"
+}
+```
+
+### Prerequisites
+
+- `screen` 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.
+
+### Run in the background and report tasks (Experimental)
+
+> This functionality is in early access and subject to change. Do not run in
+> production as it is unstable. Instead, deploy these changes into a demo or
+> staging environment.
+>
+> Join our [Discord channel](https://discord.gg/coder) or
+> [contact us](https://coder.com/contact) to get help or share feedback.
+
+```tf
+module "coder-login" {
+ count = data.coder_workspace.me.start_count
+ source = "registry.coder.com/modules/coder-login/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+}
+
+variable "anthropic_api_key" {
+ type = string
+ description = "The Anthropic API key"
+ sensitive = true
+}
+
+data "coder_parameter" "ai_prompt" {
+ type = "string"
+ name = "AI Prompt"
+ default = ""
+ description = "Write a prompt for Goose"
+ mutable = true
+}
+
+# Set the prompt and system prompt for Goose via environment variables
+resource "coder_agent" "main" {
+ # ...
+ env = {
+ GOOSE_SYSTEM_PROMPT = <<-EOT
+ You are a helpful assistant that can help write code.
+
+ Run all long running tasks (e.g. npm run dev) in the background and not in the foreground.
+
+ Periodically check in on background tasks.
+
+ Notify Coder of the status of the task before and after your steps.
+ EOT
+ GOOSE_TASK_PROMPT = data.coder_parameter.ai_prompt.value
+
+ # An API key is required for experiment_auto_configure
+ # See https://block.github.io/goose/docs/getting-started/providers
+ ANTHROPIC_API_KEY = var.anthropic_api_key # or use a coder_parameter
+ }
+}
+
+module "goose" {
+ count = data.coder_workspace.me.start_count
+ source = "registry.coder.com/modules/goose/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+ folder = "/home/coder"
+ install_goose = true
+ goose_version = "v1.0.16"
+
+ # Enable experimental features
+ experiment_report_tasks = true
+
+ # Avoid configuring Goose manually
+ experiment_auto_configure = true
+
+ # Required for experiment_auto_configure
+ experiment_goose_provider = "anthropic"
+ experiment_goose_model = "claude-3-5-sonnet-latest"
+}
+```
+
+## 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.
+
+```tf
+module "goose" {
+ source = "registry.coder.com/modules/goose/coder"
+ version = "1.0.31"
+ agent_id = coder_agent.example.id
+ folder = "/home/coder"
+ install_goose = true
+ goose_version = "v1.0.16"
+
+ # Icon is not available in Coder v2.20 and below, so we'll use a custom icon URL
+ icon = "https://raw.githubusercontent.com/block/goose/refs/heads/main/ui/desktop/src/images/icon.svg"
+}
+```
diff --git a/goose/main.tf b/goose/main.tf
new file mode 100644
index 00000000..fcb6baaa
--- /dev/null
+++ b/goose/main.tf
@@ -0,0 +1,207 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ coder = {
+ source = "coder/coder"
+ version = ">= 0.17"
+ }
+ }
+}
+
+variable "agent_id" {
+ type = string
+ description = "The ID of a Coder agent."
+}
+
+data "coder_workspace" "me" {}
+
+data "coder_workspace_owner" "me" {}
+
+variable "order" {
+ type = number
+ description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)."
+ default = null
+}
+
+variable "icon" {
+ type = string
+ description = "The icon to use for the app."
+ default = "/icon/goose.svg"
+}
+
+variable "folder" {
+ type = string
+ description = "The folder to run Goose in."
+ default = "/home/coder"
+}
+
+variable "install_goose" {
+ type = bool
+ description = "Whether to install Goose."
+ default = true
+}
+
+variable "goose_version" {
+ type = string
+ description = "The version of Goose to install."
+ default = "stable"
+}
+
+variable "experiment_use_screen" {
+ type = bool
+ description = "Whether to use screen for running Goose in the background."
+ default = false
+}
+
+variable "experiment_report_tasks" {
+ type = bool
+ description = "Whether to enable task reporting."
+ default = false
+}
+
+variable "experiment_auto_configure" {
+ type = bool
+ description = "Whether to automatically configure Goose."
+ default = false
+}
+
+variable "experiment_goose_provider" {
+ type = string
+ description = "The provider to use for Goose (e.g., anthropic)."
+ default = null
+}
+
+variable "experiment_goose_model" {
+ type = string
+ description = "The model to use for Goose (e.g., claude-3-5-sonnet-latest)."
+ default = null
+}
+
+# Install and Initialize Goose
+resource "coder_script" "goose" {
+ agent_id = var.agent_id
+ display_name = "Goose"
+ icon = var.icon
+ script = <<-EOT
+ #!/bin/bash
+ set -e
+
+ # Function to check if a command exists
+ command_exists() {
+ command -v "$1" >/dev/null 2>&1
+ }
+
+ # Install Goose if enabled
+ if [ "${var.install_goose}" = "true" ]; then
+ if ! command_exists npm; then
+ echo "Error: npm is not installed. Please install Node.js and npm first."
+ exit 1
+ fi
+ echo "Installing Goose..."
+ RELEASE_TAG=v${var.goose_version} curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash
+ fi
+
+ # Configure Goose if auto-configure is enabled
+ if [ "${var.experiment_auto_configure}" = "true" ]; then
+ echo "Configuring Goose..."
+ mkdir -p "$HOME/.config/goose"
+ cat > "$HOME/.config/goose/config.yaml" << EOL
+GOOSE_PROVIDER: ${var.experiment_goose_provider}
+GOOSE_MODEL: ${var.experiment_goose_model}
+extensions:
+ coder:
+ args:
+ - exp
+ - mcp
+ - server
+ cmd: coder
+ description: Report ALL tasks and statuses (in progress, done, failed) before and after starting
+ enabled: true
+ envs:
+ CODER_MCP_APP_STATUS_SLUG: goose
+ name: Coder
+ timeout: 3000
+ type: stdio
+ developer:
+ display_name: Developer
+ enabled: true
+ name: developer
+ timeout: 300
+ type: builtin
+EOL
+ fi
+
+ # Run with screen if enabled
+ if [ "${var.experiment_use_screen}" = "true" ]; then
+ echo "Running Goose in the background..."
+
+ # Check if screen is installed
+ if ! command_exists screen; then
+ echo "Error: screen is not installed. Please install screen manually."
+ exit 1
+ fi
+
+ touch "$HOME/.goose.log"
+
+ # Ensure the screenrc exists
+ if [ ! -f "$HOME/.screenrc" ]; then
+ echo "Creating ~/.screenrc and adding multiuser settings..." | tee -a "$HOME/.goose.log"
+ echo -e "multiuser on\nacladd $(whoami)" > "$HOME/.screenrc"
+ fi
+
+ if ! grep -q "^multiuser on$" "$HOME/.screenrc"; then
+ echo "Adding 'multiuser on' to ~/.screenrc..." | tee -a "$HOME/.goose.log"
+ echo "multiuser on" >> "$HOME/.screenrc"
+ fi
+
+ if ! grep -q "^acladd $(whoami)$" "$HOME/.screenrc"; then
+ echo "Adding 'acladd $(whoami)' to ~/.screenrc..." | tee -a "$HOME/.goose.log"
+ echo "acladd $(whoami)" >> "$HOME/.screenrc"
+ fi
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+
+ screen -U -dmS goose bash -c '
+ cd ${var.folder}
+ $HOME/.local/bin/goose run --text "$GOOSE_SYSTEM_PROMPT. Your task: $GOOSE_TASK_PROMPT" --interactive | tee -a "$HOME/.goose.log"
+ exec bash
+ '
+ else
+ # Check if goose is installed before running
+ if ! command_exists $HOME/.local/bin/goose; then
+ echo "Error: Goose is not installed. Please enable install_goose or install it manually."
+ exit 1
+ fi
+ fi
+ EOT
+ run_on_start = true
+}
+
+resource "coder_app" "goose" {
+ slug = "goose"
+ display_name = "Goose"
+ agent_id = var.agent_id
+ command = <<-EOT
+ #!/bin/bash
+ set -e
+
+ if [ "${var.experiment_use_screen}" = "true" ]; then
+ if screen -list | grep -q "goose"; then
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+ echo "Attaching to existing Goose session." | tee -a "$HOME/.goose.log"
+ screen -xRR goose
+ else
+ echo "Starting a new Goose session." | tee -a "$HOME/.goose.log"
+ screen -S goose bash -c 'export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; $HOME/.local/bin/goose run --text "Always report status and instructions to Coder, before and after your steps" --interactive | tee -a "$HOME/.goose.log"; exec bash'
+ fi
+ else
+ cd ${var.folder}
+ export LANG=en_US.UTF-8
+ export LC_ALL=en_US.UTF-8
+ $HOME/.local/bin/goose
+ fi
+ EOT
+ icon = var.icon
+}