diff --git a/.github/workflows/dogfood.yaml b/.github/workflows/dogfood.yaml
index db3292392db19..6735f7d2ce8ae 100644
--- a/.github/workflows/dogfood.yaml
+++ b/.github/workflows/dogfood.yaml
@@ -169,6 +169,7 @@ jobs:
CODER_URL: https://dev.coder.com
CODER_SESSION_TOKEN: ${{ secrets.CODER_SESSION_TOKEN }}
# Template source & details
+ TF_VAR_CODER_DOGFOOD_ANTHROPIC_API_KEY: ${{ secrets.CODER_DOGFOOD_ANTHROPIC_API_KEY }}
TF_VAR_CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }}
TF_VAR_CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }}
TF_VAR_CODER_TEMPLATE_DIR: ./coder
diff --git a/dogfood/coder/main.tf b/dogfood/coder/main.tf
index ae4088ec40fe7..8ec22dfb56351 100644
--- a/dogfood/coder/main.tf
+++ b/dogfood/coder/main.tf
@@ -38,6 +38,7 @@ locals {
repo_base_dir = data.coder_parameter.repo_base_dir.value == "~" ? "/home/coder" : replace(data.coder_parameter.repo_base_dir.value, "/^~\\//", "/home/coder/")
repo_dir = replace(try(module.git-clone[0].repo_dir, ""), "/^~\\//", "/home/coder/")
container_name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
+ has_ai_prompt = data.coder_parameter.ai_prompt.value != ""
}
data "coder_workspace_preset" "cpt" {
@@ -150,6 +151,13 @@ data "coder_parameter" "image_type" {
}
}
+variable "anthropic_api_key" {
+ type = string
+ description = "The API key used to authenticate with the Anthropic API."
+ default = ""
+ sensitive = true
+}
+
locals {
default_regions = {
// keys should match group names
@@ -242,6 +250,14 @@ data "coder_parameter" "devcontainer_autostart" {
mutable = true
}
+data "coder_parameter" "ai_prompt" {
+ type = "string"
+ name = "AI Prompt"
+ default = ""
+ description = "Prompt for Claude Code"
+ mutable = false
+}
+
provider "docker" {
host = lookup(local.docker_host, data.coder_parameter.region.value)
}
@@ -380,6 +396,24 @@ module "devcontainers-cli" {
agent_id = coder_agent.dev.id
}
+module "claude-code" {
+ count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
+ source = "dev.registry.coder.com/coder/claude-code/coder"
+ version = "~>2.0"
+ agent_id = coder_agent.dev.id
+ folder = local.repo_dir
+ install_claude_code = true
+ claude_code_version = "latest"
+ order = 999
+
+ experiment_report_tasks = true
+ experiment_post_install_script = <<-EOT
+ claude mcp add playwright npx -- @playwright/mcp@latest --headless --isolated --no-sandbox
+ claude mcp add desktop-commander npx -- @wonderwhy-er/desktop-commander@latest
+ EOT
+}
+
+
resource "coder_agent" "dev" {
arch = "amd64"
os = "linux"
@@ -710,4 +744,129 @@ resource "coder_metadata" "container_info" {
key = "region"
value = data.coder_parameter.region.option[index(data.coder_parameter.region.option.*.value, data.coder_parameter.region.value)].name
}
+ item {
+ key = "ai_task"
+ value = local.has_ai_prompt ? "yes" : "no"
+ }
+}
+
+resource "coder_env" "claude_system_prompt" {
+ count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
+ agent_id = coder_agent.dev.id
+ name = "CODER_MCP_CLAUDE_SYSTEM_PROMPT"
+ value = <<-EOT
+
+ -- Framing --
+ You are a helpful Coding assistant. Aim to autonomously investigate
+ and solve issues the user gives you and test your work, whenever possible.
+
+ Avoid shortcuts like mocking tests. When you get stuck, you can ask the user
+ but opt for autonomy.
+
+ -- Tool Selection --
+ - coder_report_task: providing status updates or requesting user input.
+ - playwright: previewing your changes after you made them
+ to confirm it worked as expected
+ - desktop-commander - use only for commands that keep running
+ (servers, dev watchers, GUI apps).
+ - Built-in tools - use for everything else:
+ (file operations, git commands, builds & installs, one-off shell commands)
+
+ Remember this decision rule:
+ - Stays running? → desktop-commander
+ - Finishes immediately? → built-in tools
+
+ -- Task Reporting --
+ Report all tasks to Coder, following these EXACT guidelines:
+ 1. Be granular. If you are investigating with multiple steps, report each step
+ to coder.
+ 2. IMMEDIATELY report status after receiving ANY user message
+ 3. Use "state": "working" when actively processing WITHOUT needing
+ additional user input
+ 4. Use "state": "complete" only when finished with a task
+ 5. Use "state": "failure" when you need ANY user input, lack sufficient
+ details, or encounter blockers
+
+ In your summary:
+ - Be specific about what you're doing
+ - Clearly indicate what information you need from the user when in
+ "failure" state
+ - Keep it under 160 characters
+ - Make it actionable
+
+ -- Context --
+ There is an existing application in the current directory.
+ Be sure to read CLAUDE.md before making any changes.
+
+ This is a real-world production application. As such, make sure to think carefully, use TODO lists, and plan carefully before making changes.
+
+ EOT
+}
+
+resource "coder_env" "claude_task_prompt" {
+ count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
+ agent_id = coder_agent.dev.id
+ name = "CODER_MCP_CLAUDE_TASK_PROMPT"
+ value = data.coder_parameter.ai_prompt.value
+}
+
+resource "coder_env" "anthropic_api_key" {
+ count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
+ agent_id = coder_agent.dev.id
+ name = "ANTHROPIC_API_KEY"
+ value = var.anthropic_api_key
+}
+
+resource "coder_app" "develop_sh" {
+ count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
+ agent_id = coder_agent.dev.id
+ slug = "develop-sh"
+ display_name = "develop.sh"
+ icon = "${data.coder_workspace.me.access_url}/emojis/1f4bb.png" // 💻
+ command = "screen -x develop_sh"
+ share = "authenticated"
+ subdomain = true
+ open_in = "tab"
+ order = 0
+}
+
+resource "coder_script" "develop_sh" {
+ count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
+ display_name = "develop.sh"
+ agent_id = coder_agent.dev.id
+ run_on_start = true
+ start_blocks_login = false
+ icon = "${data.coder_workspace.me.access_url}/emojis/1f4bb.png" // 💻
+ script = <<-EOT
+ #!/usr/bin/env bash
+ set -eux -o pipefail
+
+ # Wait for the agent startup script to finish.
+ for attempt in {1..60}; do
+ if [[ -f /tmp/.coder-startup-script.done ]]; then
+ break
+ fi
+ echo "Waiting for agent startup script to finish... ($attempt/60)"
+ sleep 10
+ done
+ cd "${local.repo_dir}" && screen -dmS develop_sh /bin/sh -c 'while true; do ./scripts/develop.sh --; echo "develop.sh exited with code $? restarting in 30s"; sleep 30; done'
+ EOT
+}
+
+resource "coder_app" "preview" {
+ count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
+ agent_id = coder_agent.dev.id
+ slug = "preview"
+ display_name = "Preview"
+ icon = "${data.coder_workspace.me.access_url}/emojis/1f50e.png" // 🔎
+ url = "http://localhost:8080"
+ share = "authenticated"
+ subdomain = true
+ open_in = "tab"
+ order = 1
+ healthcheck {
+ url = "http://localhost:8080/healthz"
+ interval = 5
+ threshold = 15
+ }
}
diff --git a/dogfood/main.tf b/dogfood/main.tf
index 72cd868f61645..c79e950efadf4 100644
--- a/dogfood/main.tf
+++ b/dogfood/main.tf
@@ -33,6 +33,13 @@ variable "CODER_TEMPLATE_MESSAGE" {
type = string
}
+variable "CODER_DOGFOOD_ANTHROPIC_API_KEY" {
+ type = string
+ description = "The API key that workspaces will use to authenticate with the Anthropic API."
+ default = ""
+ sensitive = true
+}
+
resource "coderd_template" "dogfood" {
name = var.CODER_TEMPLATE_NAME
display_name = "Write Coder on Coder"
@@ -45,6 +52,12 @@ resource "coderd_template" "dogfood" {
message = var.CODER_TEMPLATE_MESSAGE
directory = var.CODER_TEMPLATE_DIR
active = true
+ tf_vars = [
+ {
+ name = "anthropic_api_key"
+ value = var.CODER_DOGFOOD_ANTHROPIC_API_KEY
+ }
+ ]
}
]
acl = {
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy