Skip to content

Commit 15189aa

Browse files
committed
feat(dogfood): integrate tasks support
1 parent 9cde6e6 commit 15189aa

File tree

3 files changed

+172
-0
lines changed

3 files changed

+172
-0
lines changed

.github/workflows/dogfood.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ jobs:
169169
CODER_URL: https://dev.coder.com
170170
CODER_SESSION_TOKEN: ${{ secrets.CODER_SESSION_TOKEN }}
171171
# Template source & details
172+
TF_VAR_CODER_DOGFOOD_ANTHROPIC_API_KEY: ${{ secrets.CODER_DOGFOOD_ANTHROPIC_API_KEY }}
172173
TF_VAR_CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }}
173174
TF_VAR_CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }}
174175
TF_VAR_CODER_TEMPLATE_DIR: ./coder

dogfood/coder/main.tf

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ locals {
3838
repo_base_dir = data.coder_parameter.repo_base_dir.value == "~" ? "/home/coder" : replace(data.coder_parameter.repo_base_dir.value, "/^~\\//", "/home/coder/")
3939
repo_dir = replace(try(module.git-clone[0].repo_dir, ""), "/^~\\//", "/home/coder/")
4040
container_name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
41+
has_ai_prompt = data.coder_parameter.ai_prompt.value != ""
4142
}
4243

4344
data "coder_workspace_preset" "cpt" {
@@ -150,6 +151,13 @@ data "coder_parameter" "image_type" {
150151
}
151152
}
152153

154+
variable "anthropic_api_key" {
155+
type = string
156+
description = "The API key used to authenticate with the Anthropic API."
157+
default = ""
158+
sensitive = true
159+
}
160+
153161
locals {
154162
default_regions = {
155163
// keys should match group names
@@ -242,6 +250,14 @@ data "coder_parameter" "devcontainer_autostart" {
242250
mutable = true
243251
}
244252

253+
data "coder_parameter" "ai_prompt" {
254+
type = "string"
255+
name = "AI Prompt"
256+
default = ""
257+
description = "Prompt for Claude Code"
258+
mutable = false
259+
}
260+
245261
provider "docker" {
246262
host = lookup(local.docker_host, data.coder_parameter.region.value)
247263
}
@@ -380,6 +396,24 @@ module "devcontainers-cli" {
380396
agent_id = coder_agent.dev.id
381397
}
382398

399+
module "claude-code" {
400+
count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
401+
source = "dev.registry.coder.com/coder/claude-code/coder"
402+
version = "~>2.0"
403+
agent_id = coder_agent.dev.id
404+
folder = local.repo_dir
405+
install_claude_code = true
406+
claude_code_version = "latest"
407+
order = 999
408+
409+
experiment_report_tasks = true
410+
experiment_post_install_script = <<-EOT
411+
claude mcp add playwright npx -- @playwright/mcp@latest --headless --isolated --no-sandbox
412+
claude mcp add desktop-commander npx -- @wonderwhy-er/desktop-commander@latest
413+
EOT
414+
}
415+
416+
383417
resource "coder_agent" "dev" {
384418
arch = "amd64"
385419
os = "linux"
@@ -710,4 +744,128 @@ resource "coder_metadata" "container_info" {
710744
key = "region"
711745
value = data.coder_parameter.region.option[index(data.coder_parameter.region.option.*.value, data.coder_parameter.region.value)].name
712746
}
747+
item {
748+
key = "ai_task"
749+
value = local.has_ai_prompt ? "yes" : "no"
750+
}
751+
}
752+
753+
resource "coder_env" "claude_system_prompt" {
754+
count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
755+
agent_id = coder_agent.dev.id
756+
name = "CODER_MCP_CLAUDE_SYSTEM_PROMPT"
757+
value = <<-EOT
758+
<system>
759+
-- Framing --
760+
You are a helpful Coding assistant. Aim to autonomously investigate
761+
and solve issues the user gives you and test your work, whenever possible.
762+
763+
Avoid shortcuts like mocking tests. When you get stuck, you can ask the user
764+
but opt for autonomy.
765+
766+
-- Tool Selection --
767+
- coder_report_task: providing status updates or requesting user input.
768+
- playwright: previewing your changes after you made them
769+
to confirm it worked as expected
770+
- desktop-commander - use only for commands that keep running
771+
(servers, dev watchers, GUI apps).
772+
- Built-in tools - use for everything else:
773+
(file operations, git commands, builds & installs, one-off shell commands)
774+
775+
Remember this decision rule:
776+
- Stays running? → desktop-commander
777+
- Finishes immediately? → built-in tools
778+
779+
-- Task Reporting --
780+
Report all tasks to Coder, following these EXACT guidelines:
781+
1. Be granular. If you are investigating with multiple steps, report each step
782+
to coder.
783+
2. IMMEDIATELY report status after receiving ANY user message
784+
3. Use "state": "working" when actively processing WITHOUT needing
785+
additional user input
786+
4. Use "state": "complete" only when finished with a task
787+
5. Use "state": "failure" when you need ANY user input, lack sufficient
788+
details, or encounter blockers
789+
790+
In your summary:
791+
- Be specific about what you're doing
792+
- Clearly indicate what information you need from the user when in
793+
"failure" state
794+
- Keep it under 160 characters
795+
- Make it actionable
796+
797+
-- Context --
798+
There is an existing application in the current directory.
799+
Be sure to read CLAUDE.md before making any changes.
800+
801+
This is a real-world production application. As such, make sure to think carefully, use TODO lists, and plan carefully before making changes.
802+
</system>
803+
EOT
804+
}
805+
806+
resource "coder_env" "claude_task_prompt" {
807+
count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
808+
agent_id = coder_agent.dev.id
809+
name = "CODER_MCP_CLAUDE_TASK_PROMPT"
810+
value = data.coder_parameter.ai_prompt.value
811+
}
812+
813+
resource "coder_env" "anthropic_api_key" {
814+
count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
815+
agent_id = coder_agent.dev.id
816+
name = "ANTHROPIC_API_KEY"
817+
value = var.anthropic_api_key
818+
}
819+
820+
resource "coder_app" "develop_sh" {
821+
count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
822+
agent_id = coder_agent.dev.id
823+
slug = "develop-sh"
824+
display_name = "develop.sh"
825+
icon = "${data.coder_workspace.me.access_url}/emojis/1f4bb.png" // 💻
826+
command = "screen -x develop_sh"
827+
share = "authenticated"
828+
subdomain = true
829+
open_in = "tab"
830+
order = 0
831+
}
832+
833+
resource "coder_script" "develop_sh" {
834+
count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
835+
display_name = "develop.sh"
836+
agent_id = coder_agent.dev.id
837+
run_on_start = true
838+
start_blocks_login = false
839+
script = <<-EOT
840+
#!/usr/bin/env bash
841+
set -eux -o pipefail
842+
843+
# Wait for the agent startup script to finish.
844+
for attempt in {1..60}; do
845+
if [[ -f /tmp/.coder-startup-script.done ]]; then
846+
break
847+
fi
848+
echo "Waiting for agent startup script to finish... ($attempt/60)"
849+
sleep 10
850+
done
851+
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'
852+
EOT
853+
}
854+
855+
resource "coder_app" "preview" {
856+
count = local.has_ai_prompt ? data.coder_workspace.me.start_count : 0
857+
agent_id = coder_agent.dev.id
858+
slug = "preview"
859+
display_name = "Preview"
860+
icon = "${data.coder_workspace.me.access_url}/emojis/1f50e.png" // 🔎
861+
url = "http://localhost:8080"
862+
share = "authenticated"
863+
subdomain = true
864+
open_in = "tab"
865+
order = 1
866+
healthcheck {
867+
url = "http://localhost:8080/healthz"
868+
interval = 5
869+
threshold = 15
870+
}
713871
}

dogfood/main.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ variable "CODER_TEMPLATE_MESSAGE" {
3333
type = string
3434
}
3535

36+
variable "CODER_DOGFOOD_ANTHROPIC_API_KEY" {
37+
type = string
38+
description = "The API key that workspaces will use to authenticate with the Anthropic API."
39+
default = ""
40+
sensitive = true
41+
}
42+
3643
resource "coderd_template" "dogfood" {
3744
name = var.CODER_TEMPLATE_NAME
3845
display_name = "Write Coder on Coder"
@@ -45,6 +52,12 @@ resource "coderd_template" "dogfood" {
4552
message = var.CODER_TEMPLATE_MESSAGE
4653
directory = var.CODER_TEMPLATE_DIR
4754
active = true
55+
tf_vars = [
56+
{
57+
name = "anthropic_api_key"
58+
value = var.CODER_DOGFOOD_ANTHROPIC_API_KEY
59+
}
60+
]
4861
}
4962
]
5063
acl = {

0 commit comments

Comments
 (0)