Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 7 additions & 1 deletion registry/coder/modules/agent-relay-cursor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ parameters the relay stamps on each build and runs the Cursor CLI worker.
```tf
module "cursor_worker" {
source = "registry.coder.com/coder/agent-relay-cursor/coder"
version = "0.3.0"
version = "0.4.0"
agent_id = coder_agent.main.id

# Downloads the Cursor CLI at start when it is not in the image. Bake
Expand Down Expand Up @@ -58,6 +58,12 @@ created.
- Repo-scoped pools: the template must clone `agent_relay_cursor_repo_url` and
provide SCM credentials before this module's script runs.
- `computer_use = true` needs the computer-use packages in the image.
`share_desktop = true` (requires `computer_use`) lets people watch or take
control of the agent's desktop from the Desktop tab in Cursor. It needs
TigerVNC and Xfce in the image, as in
`ghcr.io/coder/agent-relay-workspace:desktop`, and `DISPLAY` must be unset
so the worker starts its own managed desktop. Run `agent worker debug` in
the image to check.
- Builds must finish inside the pool's `dispatch_deadline` (default 10m, max
15m): pre-pulled images, no persistent volumes.

Expand Down
15 changes: 15 additions & 0 deletions registry/coder/modules/agent-relay-cursor/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,21 @@ describe("agent-relay-cursor", () => {
expect(args).toContain("--computer-use");
});

it("passes an explicit desktop share mode so it cannot swallow start", async () => {
// --share-desktop takes an optional mode; bare, it consumes the
// next argument and the CLI rejects "start" as a mode.
const { id, scripts } = await setup({
computer_use: "true",
share_desktop: "true",
});
await stubAgent(id, 'printf "%s\\n" "$@" >/tmp/agent-args; sleep 30');
const { start } = await runDispatched(id, scripts);
expect(start.exitCode).toBe(0);
const args = (await readFileContainer(id, "/tmp/agent-args")).split("\n");
expect(args).toContain("--share-desktop=view_and_control");
expect(args).toContain("start");
});

it("records the exit code when the worker exits", async () => {
const { id, scripts } = await setup();
await stubAgent(id, "exit 3");
Expand Down
12 changes: 12 additions & 0 deletions registry/coder/modules/agent-relay-cursor/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ variable "computer_use" {
description = "Start the worker with --computer-use. Requires the computer-use packages in the workspace image."
}

variable "share_desktop" {
type = bool
default = false
description = "Start the worker with --share-desktop so viewers in Cursor can watch or control the agent's managed desktop. Linux only; requires computer_use and the TigerVNC and Xfce packages in the workspace image."

validation {
condition = !var.share_desktop || var.computer_use
error_message = "share_desktop requires computer_use = true."
}
}

variable "state_file" {
type = string
default = "$HOME/.coder-modules/coder/agent-relay-cursor/worker-state"
Expand Down Expand Up @@ -273,6 +284,7 @@ locals {
cli_binary = var.cli_binary
install_cli = var.install_cli
computer_use = var.computer_use
share_desktop = var.share_desktop
state_file = var.state_file
log_file = var.log_file
})
Expand Down
29 changes: 29 additions & 0 deletions registry/coder/modules/agent-relay-cursor/main.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,35 @@ run "computer_use_enabled" {
condition = can(regex("--computer-use", local.start_script))
error_message = "computer_use = true must pass the flag to the worker"
}

assert {
condition = !can(regex("--share-desktop", local.start_script))
error_message = "desktop sharing must stay opt in"
}
}

run "share_desktop_enabled" {
command = plan

variables {
computer_use = true
share_desktop = true
}

assert {
condition = can(regex("--share-desktop=view_and_control", local.start_script))
error_message = "share_desktop must pass an explicit mode, or the optional argument swallows start"
}
}

run "share_desktop_requires_computer_use" {
command = plan

variables {
share_desktop = true
}

expect_failures = [var.share_desktop]
}

run "install_cli_enabled_by_default" {
Expand Down
3 changes: 3 additions & 0 deletions registry/coder/modules/agent-relay-cursor/start.sh.tftpl
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ ${cli_binary} worker \\
\$${auth_args[@]+"\$${auth_args[@]}"} \\
%{ if computer_use ~}
--computer-use \\
%{ endif ~}
%{ if share_desktop ~}
--share-desktop=view_and_control \\
%{ endif ~}
start >"$log_file" 2>&1 &
worker_pid=\$!
Expand Down
Loading