Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions registry/coder/modules/claude-code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ module "claude-code" {

## Troubleshooting

By default, this module is configured to run the embedded chat interface as a path-based application. In production, we recommend that you configure a [wildcard access URL](https://coder.com/docs/admin/setup#wildcard-access-url) and set `subdomain = true`.

The module will create log files in the workspace's `~/.claude-module` directory. If you run into any issues, look at them for more information.
35 changes: 34 additions & 1 deletion registry/coder/modules/claude-code/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
afterEach,
expect,
describe,
it,
setDefaultTimeout,
beforeAll,
} from "bun:test";
Expand Down Expand Up @@ -100,6 +101,7 @@ const writeAgentAPIMockControl = async ({
interface SetupProps {
skipAgentAPIMock?: boolean;
skipClaudeMock?: boolean;
extraVars?: Record<string, string>;
}

const projectDir = "/home/coder/project";
Expand All @@ -112,6 +114,7 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => {
install_claude_code: "false",
agentapi_version: "preview",
folder: projectDir,
...props?.extraVars,
},
});
await execContainer(id, ["bash", "-c", `mkdir -p '${projectDir}'`]);
Expand Down Expand Up @@ -335,6 +338,36 @@ describe("claude-code", async () => {
id,
"/home/coder/agentapi-mock.log",
);
expect(agentApiStartLog).toContain("AGENTAPI_ALLOWED_HOSTS: *");
expect(agentApiStartLog).toContain("AGENTAPI_ALLOWED_HOSTS=*");
});

describe("subdomain", async () => {
it("sets AGENTAPI_CHAT_BASE_PATH when false", async () => {
const { id } = await setup();
const respModuleScript = await execModuleScript(id);
expect(respModuleScript.exitCode).toBe(0);
await expectAgentAPIStarted(id);
const agentApiStartLog = await readFileContainer(
id,
"/home/coder/agentapi-mock.log",
);
expect(agentApiStartLog).toContain(
"AGENTAPI_CHAT_BASE_PATH=/@default/default.foo/apps/ccw/chat",
);
});

it("does not set AGENTAPI_CHAT_BASE_PATH when true", async () => {
const { id } = await setup({
extraVars: { subdomain: "true" },
});
const respModuleScript = await execModuleScript(id);
expect(respModuleScript.exitCode).toBe(0);
await expectAgentAPIStarted(id);
const agentApiStartLog = await readFileContainer(
id,
"/home/coder/agentapi-mock.log",
);
expect(agentApiStartLog).toMatch(/AGENTAPI_CHAT_BASE_PATH=$/m);
});
});
});
8 changes: 4 additions & 4 deletions registry/coder/modules/claude-code/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ variable "agentapi_version" {
variable "subdomain" {
type = bool
description = "Whether to use a subdomain for the Claude Code app."
default = true
default = false
}

locals {
# we have to trim the slash because otherwise coder exp mcp will
# set up an invalid claude config
# set up an invalid claude config
workdir = trimsuffix(var.folder, "/")
encoded_pre_install_script = var.experiment_pre_install_script != null ? base64encode(var.experiment_pre_install_script) : ""
encoded_post_install_script = var.experiment_post_install_script != null ? base64encode(var.experiment_post_install_script) : ""
Expand Down Expand Up @@ -244,7 +244,7 @@ resource "coder_script" "claude_code" {

# Disable host header check since AgentAPI is proxied by Coder (which does its own validation)
export AGENTAPI_ALLOWED_HOSTS="*"

# Set chat base path for non-subdomain routing (only set if not using subdomain)
export AGENTAPI_CHAT_BASE_PATH="${local.agentapi_chat_base_path}"

Expand Down Expand Up @@ -295,4 +295,4 @@ resource "coder_ai_task" "claude_code" {
sidebar_app {
id = coder_app.claude_code_web.id
}
}
}
3 changes: 2 additions & 1 deletion registry/coder/modules/claude-code/testdata/agentapi-mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ if (

fs.writeFileSync(
"/home/coder/agentapi-mock.log",
`AGENTAPI_ALLOWED_HOSTS: ${process.env.AGENTAPI_ALLOWED_HOSTS}`,
`AGENTAPI_ALLOWED_HOSTS=${process.env.AGENTAPI_ALLOWED_HOSTS}
AGENTAPI_CHAT_BASE_PATH=${process.env.AGENTAPI_CHAT_BASE_PATH}`,
);

console.log(`starting server on port ${port}`);
Expand Down