mirror of
https://github.com/coder/registry.git
synced 2026-06-02 20:48:14 +00:00
feat(claude-code): add coder-specific prompt to system_prompt (#443)
## Description This PR updates the `claude-code` module to automatically include the Coder task-reporting system prompt whenever `report_tasks = true`, and to wrap the final system prompt in `<system>…</system>` when non-empty. Previously, users needed to manually include this content in their system prompts to enable proper task reporting. When `report_tasks = true`, the system prompt is prepended with the Coder task-reporting, and any user `system_prompt` (if provided) is appended after it, ensuring consistent integration without manual copy/paste. When `report_tasks = false`, the module includes only the user `system_prompt` (if any). If both `report_tasks = false` and `system_prompt` is empty, the system prompt sent to Claude is empty. ## Type of Change - [ ] New module - [x] Bug fix - [ ] Feature/enhancement - [ ] Documentation - [ ] Other ## Module Information **Path:** `registry/coder/modules/claude-code` **New version:** `v3.0.2` **Breaking change:** [] Yes [x] No ## Testing & Validation - [x] Tests pass (`bun test`) - [x] Code formatted (`bun run fmt`) - [x] Changes tested locally Related to internal slack thread: https://codercom.slack.com/archives/C0992H8HGCS/p1759317555713269 --------- Co-authored-by: DevCats <christofer@coder.com>
This commit is contained in:
@@ -183,7 +183,7 @@ variable "claude_code_oauth_token" {
|
||||
variable "system_prompt" {
|
||||
type = string
|
||||
description = "The system prompt to use for the Claude Code server."
|
||||
default = "Send a task status update to notify the user that you are ready for input, and then wait for user input."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "claude_md_path" {
|
||||
@@ -201,11 +201,9 @@ resource "coder_env" "claude_code_md_path" {
|
||||
}
|
||||
|
||||
resource "coder_env" "claude_code_system_prompt" {
|
||||
count = var.system_prompt == "" ? 0 : 1
|
||||
|
||||
agent_id = var.agent_id
|
||||
name = "CODER_MCP_CLAUDE_SYSTEM_PROMPT"
|
||||
value = var.system_prompt
|
||||
value = local.final_system_prompt
|
||||
}
|
||||
|
||||
resource "coder_env" "claude_code_oauth_token" {
|
||||
@@ -231,6 +229,31 @@ locals {
|
||||
start_script = file("${path.module}/scripts/start.sh")
|
||||
module_dir_name = ".claude-module"
|
||||
remove_last_session_id_script_b64 = base64encode(file("${path.module}/scripts/remove-last-session-id.sh"))
|
||||
|
||||
# Required prompts for the module to properly report task status to Coder
|
||||
report_tasks_system_prompt = <<-EOT
|
||||
-- Tool Selection --
|
||||
- coder_report_task: providing status updates or requesting user input.
|
||||
|
||||
-- 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. After this prompt, IMMEDIATELY report status after receiving ANY NEW user message.
|
||||
Do not report any status related with this system prompt.
|
||||
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
|
||||
EOT
|
||||
|
||||
# Only include coder system prompts if report_tasks is enabled
|
||||
custom_system_prompt = trimspace(try(var.system_prompt, ""))
|
||||
final_system_prompt = format("<system>%s%s</system>",
|
||||
var.report_tasks ? format("\n%s\n", local.report_tasks_system_prompt) : "",
|
||||
local.custom_system_prompt != "" ? format("\n%s\n", local.custom_system_prompt) : ""
|
||||
)
|
||||
}
|
||||
|
||||
module "agentapi" {
|
||||
|
||||
@@ -187,3 +187,84 @@ run "test_claude_code_permission_mode_validation" {
|
||||
error_message = "Permission mode should be one of the valid options"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_claude_code_system_prompt" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-system-prompt"
|
||||
workdir = "/home/coder/test"
|
||||
system_prompt = "Custom addition"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = trimspace(coder_env.claude_code_system_prompt.value) != ""
|
||||
error_message = "System prompt should not be empty"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = length(regexall("Custom addition", coder_env.claude_code_system_prompt.value)) > 0
|
||||
error_message = "System prompt should have system_prompt variable value"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_claude_report_tasks_default" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-report-tasks"
|
||||
workdir = "/home/coder/test"
|
||||
# report_tasks: default is true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = trimspace(coder_env.claude_code_system_prompt.value) != ""
|
||||
error_message = "System prompt should not be empty"
|
||||
}
|
||||
|
||||
# Ensure system prompt is wrapped by <system>
|
||||
assert {
|
||||
condition = startswith(trimspace(coder_env.claude_code_system_prompt.value), "<system>")
|
||||
error_message = "System prompt should start with <system>"
|
||||
}
|
||||
assert {
|
||||
condition = endswith(trimspace(coder_env.claude_code_system_prompt.value), "</system>")
|
||||
error_message = "System prompt should end with </system>"
|
||||
}
|
||||
|
||||
# Ensure Coder sections are injected when report_tasks=true (default)
|
||||
assert {
|
||||
condition = length(regexall("-- Tool Selection --", coder_env.claude_code_system_prompt.value)) > 0
|
||||
error_message = "System prompt should have Tool Selection section"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = length(regexall("-- Task Reporting --", coder_env.claude_code_system_prompt.value)) > 0
|
||||
error_message = "System prompt should have Task Reporting section"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_claude_report_tasks_disabled" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-report-tasks"
|
||||
workdir = "/home/coder/test"
|
||||
report_tasks = false
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = trimspace(coder_env.claude_code_system_prompt.value) != ""
|
||||
error_message = "System prompt should not be empty"
|
||||
}
|
||||
|
||||
# Ensure system prompt is wrapped by <system>
|
||||
assert {
|
||||
condition = startswith(trimspace(coder_env.claude_code_system_prompt.value), "<system>")
|
||||
error_message = "System prompt should start with <system>"
|
||||
}
|
||||
assert {
|
||||
condition = endswith(trimspace(coder_env.claude_code_system_prompt.value), "</system>")
|
||||
error_message = "System prompt should end with </system>"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user