mirror of
https://github.com/coder/registry.git
synced 2026-06-03 04:58:15 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d057a820c1 | |||
| b4e9545c35 | |||
| 50ac3b31f6 | |||
| 056937a758 | |||
| af8b4f02fd | |||
| 2de6a57a3f |
@@ -48,7 +48,7 @@ jobs:
|
||||
- name: Validate formatting
|
||||
run: bun fmt:ci
|
||||
- name: Check for typos
|
||||
uses: crate-ci/typos@v1.36.3
|
||||
uses: crate-ci/typos@v1.37.2
|
||||
with:
|
||||
config: .github/typos.toml
|
||||
validate-readme-files:
|
||||
|
||||
@@ -495,4 +495,8 @@ When reporting bugs, include:
|
||||
4. **Breaking changes** without defaults
|
||||
5. **Not running** formatting (`bun run fmt`) and tests (`terraform test`) before submitting
|
||||
|
||||
## For Maintainers
|
||||
|
||||
Guidelines for reviewing PRs, managing releases, and maintaining the registry. [See the maintainer guide for detailed information.](./MAINTAINER.md)
|
||||
|
||||
Happy contributing! 🚀
|
||||
|
||||
@@ -48,3 +48,7 @@ Simply include that snippet inside your Coder template, defining any data depend
|
||||
## Contributing
|
||||
|
||||
We are always accepting new contributions. [Please see our contributing guide for more information.](./CONTRIBUTING.md)
|
||||
|
||||
## For Maintainers
|
||||
|
||||
Guidelines for maintainers reviewing PRs and managing releases. [See the maintainer guide for more information.](./MAINTAINER.md)
|
||||
|
||||
@@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "3.0.1"
|
||||
version = "3.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
claude_api_key = "xxxx-xxxxx-xxxx"
|
||||
@@ -49,7 +49,7 @@ data "coder_parameter" "ai_prompt" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "3.0.1"
|
||||
version = "3.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
|
||||
@@ -85,7 +85,7 @@ Run and configure Claude Code as a standalone CLI in your workspace.
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "3.0.1"
|
||||
version = "3.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder"
|
||||
install_claude_code = true
|
||||
@@ -108,7 +108,7 @@ variable "claude_code_oauth_token" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "3.0.1"
|
||||
version = "3.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
claude_code_oauth_token = var.claude_code_oauth_token
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -42,7 +42,7 @@ run "test_claude_code_with_api_key" {
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = coder_env.claude_api_key.value == "test-api-key-123"
|
||||
condition = coder_env.claude_api_key[0].value == "test-api-key-123"
|
||||
error_message = "Claude API key value should match the input"
|
||||
}
|
||||
}
|
||||
@@ -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>"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source "$HOME"/.bashrc
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME"/.bashrc
|
||||
fi
|
||||
|
||||
BOLD='\033[0;1m'
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source "$HOME"/.bashrc
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME"/.bashrc
|
||||
fi
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
command_exists() {
|
||||
|
||||
@@ -19,7 +19,7 @@ Consult the [JetBrains documentation](https://www.jetbrains.com/help/idea/prereq
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["CL", "GO", "IU", "PY", "WS"]
|
||||
@@ -37,7 +37,7 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["GO", "WS"]
|
||||
@@ -51,7 +51,7 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["IU", "PY"]
|
||||
@@ -66,7 +66,7 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["IU", "PY"]
|
||||
@@ -91,7 +91,7 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["GO", "WS"]
|
||||
@@ -109,7 +109,7 @@ Due to the highest priority of the `ide_download_link` parameter in the `(jetbra
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.3"
|
||||
version = "1.2.4"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["GO", "WS"]
|
||||
|
||||
@@ -20,7 +20,7 @@ describe("jetbrains-gateway", async () => {
|
||||
folder: "/home/coder",
|
||||
});
|
||||
expect(state.outputs.url.value).toBe(
|
||||
"jetbrains-gateway://connect#type=coder&workspace=default&owner=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz&agent_id=foo",
|
||||
"jetbrains-gateway://connect#type=coder&workspace=default&owner=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz&agent=",
|
||||
);
|
||||
|
||||
const coder_app = state.resources.find(
|
||||
@@ -40,4 +40,28 @@ describe("jetbrains-gateway", async () => {
|
||||
});
|
||||
expect(state.outputs.identifier.value).toBe("IU");
|
||||
});
|
||||
|
||||
it("optionally includes agent when an agent name is provided", async () => {
|
||||
const state = await runTerraformApply(import.meta.dir, {
|
||||
agent_id: "foo",
|
||||
agent_name: "main",
|
||||
folder: "/home/coder",
|
||||
});
|
||||
|
||||
expect(state.outputs.url.value).toBe(
|
||||
"jetbrains-gateway://connect#type=coder&workspace=default&owner=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz&agent=main",
|
||||
);
|
||||
});
|
||||
|
||||
it("includes the agent parameter even when the provided value is blank", async () => {
|
||||
const state = await runTerraformApply(import.meta.dir, {
|
||||
agent_id: "foo",
|
||||
agent_name: " ",
|
||||
folder: "/home/coder",
|
||||
});
|
||||
|
||||
expect(state.outputs.url.value).toBe(
|
||||
"jetbrains-gateway://connect#type=coder&workspace=default&owner=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN&ide_product_code=IU&ide_build_number=243.21565.193&ide_download_link=https://download.jetbrains.com/idea/ideaIU-2024.3.tar.gz&agent= ",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -30,15 +30,14 @@ variable "agent_id" {
|
||||
|
||||
variable "slug" {
|
||||
type = string
|
||||
description = "The slug for the coder_app. Allows resuing the module with the same template."
|
||||
description = "The slug for the coder_app. Allows reusing the module with the same template."
|
||||
default = "gateway"
|
||||
}
|
||||
|
||||
variable "agent_name" {
|
||||
type = string
|
||||
description = "Agent name. (unused). Will be removed in a future version"
|
||||
|
||||
default = ""
|
||||
description = "Agent name."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "folder" {
|
||||
@@ -348,8 +347,8 @@ resource "coder_app" "gateway" {
|
||||
local.build_number,
|
||||
"&ide_download_link=",
|
||||
local.download_link,
|
||||
"&agent_id=",
|
||||
var.agent_id,
|
||||
"&agent=",
|
||||
var.agent_name,
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user