chore(claude-code): use $HOME variable instead of hardcoded path and remove symlink (#592)
## Description - Remove hardcoded `/home/coder` path. - Remove symlink in favour of coder_env "PATH". ## Type of Change - [ ] New module - [ ] New template - [x] Bug fix - [ ] Feature/enhancement - [ ] Documentation - [ ] Other ## Module Information **Path:** `registry/[coder/modules/claude-code` **New version:** `v4.2.7` **Breaking change:** [ ] Yes [x] No ## Testing & Validation - [x] Tests pass (`bun test`) - [x] Code formatted (`bun fmt`) - [ ] Changes tested locally ## Related Issues <!-- Link related issues or write "None" if not applicable --> --------- Signed-off-by: 35C4n0r <work.jaykumar@gmail.com> Co-authored-by: DevelopmentCats <christofer@coder.com>
This commit is contained in:
parent
aa4890fe62
commit
a85436fdf4
@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
|
|||||||
```tf
|
```tf
|
||||||
module "claude-code" {
|
module "claude-code" {
|
||||||
source = "registry.coder.com/coder/claude-code/coder"
|
source = "registry.coder.com/coder/claude-code/coder"
|
||||||
version = "4.2.6"
|
version = "4.2.7"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
workdir = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
claude_api_key = "xxxx-xxxxx-xxxx"
|
claude_api_key = "xxxx-xxxxx-xxxx"
|
||||||
@ -45,7 +45,7 @@ This example shows how to configure the Claude Code module to run the agent behi
|
|||||||
```tf
|
```tf
|
||||||
module "claude-code" {
|
module "claude-code" {
|
||||||
source = "dev.registry.coder.com/coder/claude-code/coder"
|
source = "dev.registry.coder.com/coder/claude-code/coder"
|
||||||
version = "4.2.6"
|
version = "4.2.7"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
workdir = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
enable_boundary = true
|
enable_boundary = true
|
||||||
@ -72,7 +72,7 @@ data "coder_parameter" "ai_prompt" {
|
|||||||
|
|
||||||
module "claude-code" {
|
module "claude-code" {
|
||||||
source = "registry.coder.com/coder/claude-code/coder"
|
source = "registry.coder.com/coder/claude-code/coder"
|
||||||
version = "4.2.6"
|
version = "4.2.7"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
workdir = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
|
|
||||||
@ -92,10 +92,9 @@ module "claude-code" {
|
|||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"my-custom-tool": {
|
"my-custom-tool": {
|
||||||
"command": "my-tool-server"
|
"command": "my-tool-server",
|
||||||
"args": ["--port", "8080"]
|
"args": ["--port", "8080"]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
@ -109,7 +108,7 @@ Run and configure Claude Code as a standalone CLI in your workspace.
|
|||||||
```tf
|
```tf
|
||||||
module "claude-code" {
|
module "claude-code" {
|
||||||
source = "registry.coder.com/coder/claude-code/coder"
|
source = "registry.coder.com/coder/claude-code/coder"
|
||||||
version = "4.2.6"
|
version = "4.2.7"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
workdir = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
install_claude_code = true
|
install_claude_code = true
|
||||||
@ -131,7 +130,7 @@ variable "claude_code_oauth_token" {
|
|||||||
|
|
||||||
module "claude-code" {
|
module "claude-code" {
|
||||||
source = "registry.coder.com/coder/claude-code/coder"
|
source = "registry.coder.com/coder/claude-code/coder"
|
||||||
version = "4.2.6"
|
version = "4.2.7"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
workdir = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
claude_code_oauth_token = var.claude_code_oauth_token
|
claude_code_oauth_token = var.claude_code_oauth_token
|
||||||
@ -204,7 +203,7 @@ resource "coder_env" "bedrock_api_key" {
|
|||||||
|
|
||||||
module "claude-code" {
|
module "claude-code" {
|
||||||
source = "registry.coder.com/coder/claude-code/coder"
|
source = "registry.coder.com/coder/claude-code/coder"
|
||||||
version = "4.2.6"
|
version = "4.2.7"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
workdir = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
|
model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
|
||||||
@ -261,7 +260,7 @@ resource "coder_env" "google_application_credentials" {
|
|||||||
|
|
||||||
module "claude-code" {
|
module "claude-code" {
|
||||||
source = "registry.coder.com/coder/claude-code/coder"
|
source = "registry.coder.com/coder/claude-code/coder"
|
||||||
version = "4.2.6"
|
version = "4.2.7"
|
||||||
agent_id = coder_agent.main.id
|
agent_id = coder_agent.main.id
|
||||||
workdir = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
model = "claude-sonnet-4@20250514"
|
model = "claude-sonnet-4@20250514"
|
||||||
|
|||||||
@ -39,9 +39,11 @@ interface SetupProps {
|
|||||||
agentapiMockScript?: string;
|
agentapiMockScript?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const setup = async (props?: SetupProps): Promise<{ id: string }> => {
|
const setup = async (
|
||||||
|
props?: SetupProps,
|
||||||
|
): Promise<{ id: string; coderEnvVars: Record<string, string> }> => {
|
||||||
const projectDir = "/home/coder/project";
|
const projectDir = "/home/coder/project";
|
||||||
const { id } = await setupUtil({
|
const { id, coderEnvVars } = await setupUtil({
|
||||||
moduleDir: import.meta.dir,
|
moduleDir: import.meta.dir,
|
||||||
moduleVariables: {
|
moduleVariables: {
|
||||||
install_claude_code: props?.skipClaudeMock ? "true" : "false",
|
install_claude_code: props?.skipClaudeMock ? "true" : "false",
|
||||||
@ -61,7 +63,7 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => {
|
|||||||
content: await loadTestFile(import.meta.dir, "claude-mock.sh"),
|
content: await loadTestFile(import.meta.dir, "claude-mock.sh"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return { id };
|
return { id, coderEnvVars };
|
||||||
};
|
};
|
||||||
|
|
||||||
setDefaultTimeout(60 * 1000);
|
setDefaultTimeout(60 * 1000);
|
||||||
@ -79,14 +81,14 @@ describe("claude-code", async () => {
|
|||||||
|
|
||||||
test("install-claude-code-version", async () => {
|
test("install-claude-code-version", async () => {
|
||||||
const version_to_install = "1.0.40";
|
const version_to_install = "1.0.40";
|
||||||
const { id } = await setup({
|
const { id, coderEnvVars } = await setup({
|
||||||
skipClaudeMock: true,
|
skipClaudeMock: true,
|
||||||
moduleVariables: {
|
moduleVariables: {
|
||||||
install_claude_code: "true",
|
install_claude_code: "true",
|
||||||
claude_code_version: version_to_install,
|
claude_code_version: version_to_install,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await execModuleScript(id);
|
await execModuleScript(id, coderEnvVars);
|
||||||
const resp = await execContainer(id, [
|
const resp = await execContainer(id, [
|
||||||
"bash",
|
"bash",
|
||||||
"-c",
|
"-c",
|
||||||
@ -96,14 +98,14 @@ describe("claude-code", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("check-latest-claude-code-version-works", async () => {
|
test("check-latest-claude-code-version-works", async () => {
|
||||||
const { id } = await setup({
|
const { id, coderEnvVars } = await setup({
|
||||||
skipClaudeMock: true,
|
skipClaudeMock: true,
|
||||||
skipAgentAPIMock: true,
|
skipAgentAPIMock: true,
|
||||||
moduleVariables: {
|
moduleVariables: {
|
||||||
install_claude_code: "true",
|
install_claude_code: "true",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await execModuleScript(id);
|
await execModuleScript(id, coderEnvVars);
|
||||||
await expectAgentAPIStarted(id);
|
await expectAgentAPIStarted(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -133,13 +135,13 @@ describe("claude-code", async () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { id } = await setup({
|
const { id, coderEnvVars } = await setup({
|
||||||
skipClaudeMock: true,
|
skipClaudeMock: true,
|
||||||
moduleVariables: {
|
moduleVariables: {
|
||||||
mcp: mcpConfig,
|
mcp: mcpConfig,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await execModuleScript(id);
|
await execModuleScript(id, coderEnvVars);
|
||||||
|
|
||||||
const resp = await readFileContainer(id, "/home/coder/.claude.json");
|
const resp = await readFileContainer(id, "/home/coder/.claude.json");
|
||||||
expect(resp).toContain("test-cmd");
|
expect(resp).toContain("test-cmd");
|
||||||
|
|||||||
@ -288,6 +288,12 @@ resource "coder_env" "disable_autoupdater" {
|
|||||||
value = "1"
|
value = "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "coder_env" "claude_binary_path" {
|
||||||
|
agent_id = var.agent_id
|
||||||
|
name = "PATH"
|
||||||
|
value = "$HOME/.local/bin:$PATH"
|
||||||
|
}
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
# we have to trim the slash because otherwise coder exp mcp will
|
# we have to trim the slash because otherwise coder exp mcp will
|
||||||
# set up an invalid claude config
|
# set up an invalid claude config
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ -f "$HOME/.bashrc" ]; then
|
|
||||||
source "$HOME"/.bashrc
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set strict error handling AFTER sourcing bashrc to avoid unbound variable errors from user dotfiles
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
BOLD='\033[0;1m'
|
BOLD='\033[0;1m'
|
||||||
@ -45,11 +40,6 @@ function install_claude_code_cli() {
|
|||||||
if [ $CURL_EXIT -ne 0 ]; then
|
if [ $CURL_EXIT -ne 0 ]; then
|
||||||
echo "Claude Code installer failed with exit code $$CURL_EXIT"
|
echo "Claude Code installer failed with exit code $$CURL_EXIT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure binaries are discoverable.
|
|
||||||
echo "Creating a symlink for claude"
|
|
||||||
sudo ln -s /home/coder/.local/bin/claude /usr/local/bin/claude
|
|
||||||
|
|
||||||
echo "Installed Claude Code successfully. Version: $(claude --version || echo 'unknown')"
|
echo "Installed Claude Code successfully. Version: $(claude --version || echo 'unknown')"
|
||||||
else
|
else
|
||||||
echo "Skipping Claude Code installation as per configuration."
|
echo "Skipping Claude Code installation as per configuration."
|
||||||
|
|||||||
@ -1,14 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ -f "$HOME/.bashrc" ]; then
|
|
||||||
source "$HOME"/.bashrc
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set strict error handling AFTER sourcing bashrc to avoid unbound variable errors from user dotfiles
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
export PATH="$HOME/.local/bin:$PATH"
|
|
||||||
|
|
||||||
command_exists() {
|
command_exists() {
|
||||||
command -v "$1" > /dev/null 2>&1
|
command -v "$1" > /dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user