Compare commits

..

1 Commits

12 changed files with 46 additions and 127 deletions
+11 -6
View File
@@ -50,16 +50,16 @@ variable "sessions" {
default = ["default"]
}
resource "coder_script" "tmux" {
module "coder_utils" {
source = "registry.coder.com/coder/coder-utils/coder"
version = "0.0.1"
agent_id = var.agent_id
display_name = "tmux"
icon = "/icon/terminal.svg"
script = templatefile("${path.module}/scripts/run.sh", {
TMUX_CONFIG = base64encode(var.tmux_config)
install_script = templatefile("${path.module}/scripts/run.sh", {
TMUX_CONFIG = base64encode(var.tmux_config)
SAVE_INTERVAL = var.save_interval
})
run_on_start = true
run_on_stop = false
module_directory = "$HOME/.coder-modules/anomaly/tmux"
}
resource "coder_app" "tmux_sessions" {
@@ -76,3 +76,8 @@ resource "coder_app" "tmux_sessions" {
SESSION_NAME = each.value
})
}
output "scripts" {
description = "Ordered list of coder exp sync names for the coder_script resources this module actually creates, in run order (pre_install, install, post_install). Scripts that were not configured are absent from the list."
value = module.coder_utils.scripts
}
+1 -1
View File
@@ -101,7 +101,7 @@ module "codex" {
preferred_auth_method = "apikey"
EOT
mcp = <<-EOT
additional_mcp_servers = <<-EOT
[mcp_servers.GitHub]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
@@ -246,7 +246,7 @@ describe("codex", async () => {
].join("\n");
const { id, scripts } = await setup({
moduleVariables: {
mcp: additional,
additional_mcp_servers: additional,
},
});
await runScripts(id, scripts);
+6 -6
View File
@@ -50,8 +50,8 @@ variable "install_codex" {
variable "codex_version" {
type = string
description = "The version of Codex to install."
default = "latest"
description = "The version of Codex to install. Empty string installs the latest available version."
default = ""
}
variable "openai_api_key" {
@@ -75,16 +75,16 @@ variable "base_config_toml" {
trust_level = "trusted"
When non-empty, the value is written verbatim as the base of config.toml;
mcp and AI Gateway sections are still appended after it.
additional_mcp_servers and AI Gateway sections are still appended after it.
Note: model_reasoning_effort and workdir trust are only applied in the
default config. Include them in your custom config if needed.
EOT
default = ""
}
variable "mcp" {
variable "additional_mcp_servers" {
type = string
description = "MCP server configurations in TOML format. When set, servers are appended to the Codex config.toml."
description = "Additional MCP servers configuration in TOML format."
default = ""
}
@@ -140,7 +140,7 @@ locals {
ARG_CODEX_VERSION = var.codex_version != "" ? base64encode(var.codex_version) : ""
ARG_WORKDIR = local.workdir != "" ? base64encode(local.workdir) : ""
ARG_BASE_CONFIG_TOML = var.base_config_toml != "" ? base64encode(var.base_config_toml) : ""
ARG_MCP = var.mcp != "" ? base64encode(var.mcp) : ""
ARG_ADDITIONAL_MCP_SERVERS = var.additional_mcp_servers != "" ? base64encode(var.additional_mcp_servers) : ""
ARG_ENABLE_AI_GATEWAY = tostring(var.enable_ai_gateway)
ARG_AIBRIDGE_CONFIG = var.enable_ai_gateway ? base64encode(local.aibridge_config) : ""
ARG_MODEL_REASONING_EFFORT = var.model_reasoning_effort
@@ -12,7 +12,7 @@ ARG_INSTALL='${ARG_INSTALL}'
ARG_CODEX_VERSION=$(echo -n '${ARG_CODEX_VERSION}' | base64 -d)
ARG_WORKDIR=$(echo -n '${ARG_WORKDIR}' | base64 -d)
ARG_BASE_CONFIG_TOML=$(echo -n '${ARG_BASE_CONFIG_TOML}' | base64 -d)
ARG_MCP=$(echo -n '${ARG_MCP}' | base64 -d)
ARG_ADDITIONAL_MCP_SERVERS=$(echo -n '${ARG_ADDITIONAL_MCP_SERVERS}' | base64 -d)
ARG_ENABLE_AI_GATEWAY='${ARG_ENABLE_AI_GATEWAY}'
ARG_AIBRIDGE_CONFIG=$(echo -n '${ARG_AIBRIDGE_CONFIG}' | base64 -d)
ARG_MODEL_REASONING_EFFORT='${ARG_MODEL_REASONING_EFFORT}'
@@ -150,9 +150,9 @@ function populate_config_toml() {
write_minimal_default_config "$${config_path}"
fi
if [ -n "$${ARG_MCP}" ]; then
printf "Adding MCP servers\n"
echo "$${ARG_MCP}" >> "$${config_path}"
if [ -n "$${ARG_ADDITIONAL_MCP_SERVERS}" ]; then
printf "Adding additional MCP servers\n"
echo "$${ARG_ADDITIONAL_MCP_SERVERS}" >> "$${config_path}"
fi
if [ "$${ARG_ENABLE_AI_GATEWAY}" = "true" ] && [ -n "$${ARG_AIBRIDGE_CONFIG}" ]; then
+4 -20
View File
@@ -13,7 +13,7 @@ Run [Gemini CLI](https://github.com/google-gemini/gemini-cli) in your workspace
```tf
module "gemini" {
source = "registry.coder.com/coder-labs/gemini/coder"
version = "3.0.1"
version = "3.0.0"
agent_id = coder_agent.main.id
folder = "/home/coder/project"
}
@@ -46,7 +46,7 @@ variable "gemini_api_key" {
module "gemini" {
source = "registry.coder.com/coder-labs/gemini/coder"
version = "3.0.1"
version = "3.0.0"
agent_id = coder_agent.main.id
gemini_api_key = var.gemini_api_key
folder = "/home/coder/project"
@@ -94,7 +94,7 @@ data "coder_parameter" "ai_prompt" {
module "gemini" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder-labs/gemini/coder"
version = "3.0.1"
version = "3.0.0"
agent_id = coder_agent.main.id
gemini_api_key = var.gemini_api_key
gemini_model = "gemini-2.5-flash"
@@ -105,22 +105,6 @@ module "gemini" {
You are a helpful coding assistant. Always explain your code changes clearly.
YOU MUST REPORT ALL TASKS TO CODER.
EOT
pre_install_script = <<-EOT
#!/bin/bash
set -e
echo "Installing Node.js via NodeSource..."
sudo apt-get update -qq && sudo apt-get install -y curl ca-certificates
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo bash -
sudo apt-get install -y nodejs
echo "Node version: $(node -v)"
echo "npm version: $(npm -v)"
echo "Node install complete."
EOT
}
```
@@ -134,7 +118,7 @@ For enterprise users who prefer Google's Vertex AI platform:
```tf
module "gemini" {
source = "registry.coder.com/coder-labs/gemini/coder"
version = "3.0.1"
version = "3.0.0"
agent_id = coder_agent.main.id
gemini_api_key = var.gemini_api_key
folder = "/home/coder/project"
+8 -2
View File
@@ -148,16 +148,22 @@ locals {
base_extensions = <<-EOT
{
"coder": {
"command": "coder",
"args": [
"exp",
"mcp",
"server"
],
"command": "coder",
"description": "Report ALL tasks and statuses (in progress, done, failed) you are working on.",
"enabled": true,
"env": {
"CODER_MCP_APP_STATUS_SLUG": "${local.app_slug}",
"CODER_MCP_AI_AGENTAPI_URL": "http://localhost:3284"
}
},
"name": "Coder",
"timeout": 3000,
"type": "stdio",
"trust": true
}
}
EOT
@@ -17,7 +17,6 @@ echo "--------------------------------"
printf "gemini_config: %s\n" "$ARG_GEMINI_CONFIG"
printf "install: %s\n" "$ARG_INSTALL"
printf "gemini_version: %s\n" "$ARG_GEMINI_VERSION"
printf "BASE_EXTENSIONS: %s\n" "$BASE_EXTENSIONS"
echo "--------------------------------"
set +o nounset
@@ -141,25 +140,6 @@ function add_system_prompt_if_exists() {
fi
}
function patch_coder_mcp_command() {
CODER_BIN=$(which coder)
SETTINGS_PATH="$HOME/.gemini/settings.json"
if [ -z "$CODER_BIN" ]; then
printf "Warning: could not find coder binary, MCP command path not patched.\n"
return
fi
printf "Patching coder MCP command path to: %s\n" "$CODER_BIN"
TMP_SETTINGS=$(mktemp)
jq --arg bin "$CODER_BIN" \
'.mcpServers.coder.command = $bin' \
"$SETTINGS_PATH" > "$TMP_SETTINGS" && mv "$TMP_SETTINGS" "$SETTINGS_PATH"
printf "Patch complete.\n"
}
function configure_mcp() {
export CODER_MCP_APP_STATUS_SLUG="gemini"
export CODER_MCP_AI_AGENTAPI_URL="http://localhost:3284"
@@ -169,5 +149,4 @@ function configure_mcp() {
install_gemini
populate_settings_json
add_system_prompt_if_exists
patch_coder_mcp_command
configure_mcp
+11 -34
View File
@@ -14,7 +14,7 @@ This module allows you to automatically clone a repository by URL and skip if it
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
}
@@ -28,7 +28,7 @@ module "git-clone" {
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
base_dir = "~/projects/coder"
@@ -43,7 +43,7 @@ To use with [Git Authentication](https://coder.com/docs/v2/latest/admin/git-prov
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
}
@@ -70,7 +70,7 @@ data "coder_parameter" "git_repo" {
module "git_clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = data.coder_parameter.git_repo.value
}
@@ -105,7 +105,7 @@ Configuring `git-clone` for a self-hosted GitHub Enterprise Server running at `g
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.example.com/coder/coder/tree/feat/example"
git_providers = {
@@ -125,7 +125,7 @@ To GitLab clone with a specific branch like `feat/example`
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://gitlab.com/coder/coder/-/tree/feat/example"
}
@@ -137,7 +137,7 @@ Configuring `git-clone` for a self-hosted GitLab running at `gitlab.example.com`
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://gitlab.example.com/coder/coder/-/tree/feat/example"
git_providers = {
@@ -159,7 +159,7 @@ For example, to clone the `feat/example` branch:
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
branch_name = "feat/example"
@@ -177,7 +177,7 @@ For example, this will clone into the `~/projects/coder/coder-dev` folder:
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
folder_name = "coder-dev"
@@ -196,36 +196,13 @@ If not defined, the default, `0`, performs a full clone.
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
depth = 1
}
```
## Pre-clone script
Run a custom script before cloning the repository by setting the `pre_clone_script` variable.
This is useful for preparing the environment or validating prerequisites before cloning.
```tf
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
pre_clone_script = <<-EOT
#!/bin/bash
echo "Preparing to clone repository..."
# Check prerequisites
command -v npm >/dev/null 2>&1 || { echo "npm is required but not installed."; exit 1; }
# Set up environment
export NODE_ENV=development
EOT
}
```
## Post-clone script
Run a custom script after cloning the repository by setting the `post_clone_script` variable.
@@ -235,7 +212,7 @@ This is useful for running initialization tasks like installing dependencies or
module "git-clone" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/git-clone/coder"
version = "1.3.0"
version = "1.2.3"
agent_id = coder_agent.example.id
url = "https://github.com/coder/coder"
post_clone_script = <<-EOT
@@ -261,16 +261,4 @@ describe("git-clone", async () => {
expect(output.stdout).toContain("Running post-clone script...");
expect(output.stdout).toContain("Post-clone script executed");
});
it("runs pre-clone script", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
url: "fake-url",
pre_clone_script: "echo 'Pre-clone script executed'",
});
const output = await executeScriptInContainer(state, "alpine/git");
expect(output.stdout).toContain("Running pre-clone script...");
expect(output.stdout).toContain("Pre-clone script executed");
expect(output.stdout).toContain("Cloning fake-url to ~/fake-url...");
});
});
-9
View File
@@ -68,12 +68,6 @@ variable "post_clone_script" {
default = null
}
variable "pre_clone_script" {
description = "Custom script to run before cloning the repository. Runs before git clone, even if the repository already exists."
type = string
default = null
}
locals {
# Remove query parameters and fragments from the URL
url = replace(replace(var.url, "/\\?.*/", ""), "/#.*/", "")
@@ -95,8 +89,6 @@ locals {
web_url = startswith(local.clone_url, "git@") ? replace(replace(local.clone_url, ":", "/"), "git@", "https://") : local.clone_url
# Encode the post_clone_script for passing to the shell script
encoded_post_clone_script = var.post_clone_script != null ? base64encode(var.post_clone_script) : ""
# Encode the pre_clone_script for passing to the shell script
encoded_pre_clone_script = var.pre_clone_script != null ? base64encode(var.pre_clone_script) : ""
}
output "repo_dir" {
@@ -137,7 +129,6 @@ resource "coder_script" "git_clone" {
BRANCH_NAME : local.branch_name,
DEPTH = var.depth,
POST_CLONE_SCRIPT : local.encoded_post_clone_script,
PRE_CLONE_SCRIPT : local.encoded_pre_clone_script,
})
display_name = "Git Clone"
icon = "/icon/git.svg"
-11
View File
@@ -7,7 +7,6 @@ BRANCH_NAME="${BRANCH_NAME}"
CLONE_PATH="$${CLONE_PATH/#\~/$${HOME}}"
DEPTH="${DEPTH}"
POST_CLONE_SCRIPT="${POST_CLONE_SCRIPT}"
PRE_CLONE_SCRIPT="${PRE_CLONE_SCRIPT}"
# Check if the variable is empty...
if [ -z "$REPO_URL" ]; then
@@ -34,16 +33,6 @@ if [ ! -d "$CLONE_PATH" ]; then
mkdir -p "$CLONE_PATH"
fi
# Run pre-clone script if provided
if [ -n "$PRE_CLONE_SCRIPT" ]; then
echo "Running pre-clone script..."
PRE_CLONE_TMP=$(mktemp)
echo "$PRE_CLONE_SCRIPT" | base64 -d > "$PRE_CLONE_TMP"
chmod +x "$PRE_CLONE_TMP"
$PRE_CLONE_TMP
rm "$PRE_CLONE_TMP"
fi
# Check if the directory is empty
# and if it is, clone the repo, otherwise skip cloning
if [ -z "$(ls -A "$CLONE_PATH")" ]; then