diff --git a/registry/coder/modules/cursor/main.test.ts b/registry/coder/modules/cursor/main.test.ts index 268a8e63..ed92b9c9 100644 --- a/registry/coder/modules/cursor/main.test.ts +++ b/registry/coder/modules/cursor/main.test.ts @@ -12,37 +12,29 @@ describe("cursor", async () => { agent_id: "foo", }); - it("default output with CLI enabled", async () => { + it("default output", async () => { const state = await runTerraformApply(import.meta.dir, { agent_id: "foo", }); - - // Check desktop app output - expect(state.outputs.cursor_desktop_url.value).toBe( - "cursor://coder.coder-remote/open?owner=default&workspace=default&folder=/home/coder&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", + expect(state.outputs.cursor_url.value).toBe( + "cursor://coder.coder-remote/open?owner=default&workspace=default&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", ); - // Check that AgentAPI module is created - const agentapi_module = state.resources.find( - (res) => res.type === "module" && res.name === "agentapi", - ); - expect(agentapi_module).not.toBeNull(); - - // Check desktop app resource const coder_app = state.resources.find( - (res) => res.type === "coder_app" && res.name === "cursor_desktop", + (res) => res.type === "coder_app" && res.name === "cursor", ); + expect(coder_app).not.toBeNull(); expect(coder_app?.instances.length).toBe(1); expect(coder_app?.instances[0].attributes.order).toBeNull(); }); - it("adds custom folder", async () => { + it("adds folder", async () => { const state = await runTerraformApply(import.meta.dir, { agent_id: "foo", folder: "/foo/bar", }); - expect(state.outputs.cursor_desktop_url.value).toBe( + expect(state.outputs.cursor_url.value).toBe( "cursor://coder.coder-remote/open?owner=default&workspace=default&folder=/foo/bar&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", ); }); @@ -53,18 +45,29 @@ describe("cursor", async () => { folder: "/foo/bar", open_recent: "true", }); - expect(state.outputs.cursor_desktop_url.value).toBe( + expect(state.outputs.cursor_url.value).toBe( "cursor://coder.coder-remote/open?owner=default&workspace=default&folder=/foo/bar&openRecent&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", ); }); - it("adds open_recent with default folder", async () => { + it("adds folder but not open_recent", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + folder: "/foo/bar", + openRecent: "false", + }); + expect(state.outputs.cursor_url.value).toBe( + "cursor://coder.coder-remote/open?owner=default&workspace=default&folder=/foo/bar&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", + ); + }); + + it("adds open_recent", async () => { const state = await runTerraformApply(import.meta.dir, { agent_id: "foo", open_recent: "true", }); - expect(state.outputs.cursor_desktop_url.value).toBe( - "cursor://coder.coder-remote/open?owner=default&workspace=default&folder=/home/coder&openRecent&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", + expect(state.outputs.cursor_url.value).toBe( + "cursor://coder.coder-remote/open?owner=default&workspace=default&openRecent&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", ); }); @@ -75,31 +78,11 @@ describe("cursor", async () => { }); const coder_app = state.resources.find( - (res) => res.type === "coder_app" && res.name === "cursor_desktop", + (res) => res.type === "coder_app" && res.name === "cursor", ); expect(coder_app).not.toBeNull(); expect(coder_app?.instances.length).toBe(1); - expect(coder_app?.instances[0].attributes.order).toBe(23); // order + 1 for desktop app - }); - - it("disables CLI installation", async () => { - const state = await runTerraformApply(import.meta.dir, { - agent_id: "foo", - install_cursor_cli: "false", - install_agentapi: "false", - }); - - // Should still have desktop app - const coder_app = state.resources.find( - (res) => res.type === "coder_app" && res.name === "cursor_desktop", - ); - expect(coder_app).not.toBeNull(); - - // AgentAPI module should still exist but with install_agentapi = false - const agentapi_module = state.resources.find( - (res) => res.type === "module" && res.name === "agentapi", - ); - expect(agentapi_module).not.toBeNull(); + expect(coder_app?.instances[0].attributes.order).toBe(22); }); }); diff --git a/registry/coder/modules/cursor/main.tf b/registry/coder/modules/cursor/main.tf index 8292ab6f..47d35b62 100644 --- a/registry/coder/modules/cursor/main.tf +++ b/registry/coder/modules/cursor/main.tf @@ -4,7 +4,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = ">= 2.7" + version = ">= 2.5" } } } @@ -14,9 +14,17 @@ variable "agent_id" { description = "The ID of a Coder agent." } -data "coder_workspace" "me" {} +variable "folder" { + type = string + description = "The folder to open in Cursor IDE." + default = "" +} -data "coder_workspace_owner" "me" {} +variable "open_recent" { + type = bool + description = "Open the most recent workspace or folder. Falls back to the folder if there is no recent workspace or folder to open." + default = false +} variable "order" { type = number @@ -30,108 +38,28 @@ variable "group" { default = null } -variable "icon" { +variable "slug" { type = string - description = "The icon to use for the app." - default = "/icon/cursor.svg" + description = "The slug of the app." + default = "cursor" } -variable "folder" { +variable "display_name" { type = string - description = "The folder to run Cursor in." - default = "/home/coder" + description = "The display name of the app." + default = "Cursor Desktop" } -variable "open_recent" { - type = bool - description = "Open the most recent workspace or folder. Falls back to the folder if there is no recent workspace or folder to open." - default = false -} +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} -variable "install_cursor_cli" { - type = bool - description = "Whether to install Cursor CLI." - default = true -} - -variable "install_agentapi" { - type = bool - description = "Whether to install AgentAPI." - default = true -} - -variable "agentapi_version" { - type = string - description = "The version of AgentAPI to install." - default = "v0.3.3" -} - -variable "subdomain" { - type = bool - description = "Whether to use a subdomain for AgentAPI." - default = true -} - -variable "pre_install_script" { - type = string - description = "Custom script to run before installing Cursor CLI." - default = null -} - -variable "post_install_script" { - type = string - description = "Custom script to run after installing Cursor CLI." - default = null -} - -locals { - app_slug = "cursor" - install_script = file("${path.module}/scripts/install.sh") - start_script = file("${path.module}/scripts/start.sh") - module_dir_name = ".cursor-module" -} - -module "agentapi" { - source = "registry.coder.com/coder/agentapi/coder" - version = "1.1.0" - - agent_id = var.agent_id - web_app_slug = local.app_slug - web_app_order = var.order - web_app_group = var.group - web_app_icon = var.icon - web_app_display_name = "Cursor" - cli_app_slug = "${local.app_slug}-cli" - cli_app_display_name = "Cursor CLI" - module_dir_name = local.module_dir_name - install_agentapi = var.install_agentapi - agentapi_version = var.agentapi_version - agentapi_subdomain = var.subdomain - pre_install_script = var.pre_install_script - post_install_script = var.post_install_script - start_script = local.start_script - install_script = <<-EOT - #!/bin/bash - set -o errexit - set -o pipefail - - echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh - chmod +x /tmp/install.sh - - ARG_FOLDER='${var.folder}' \ - ARG_INSTALL='${var.install_cursor_cli}' \ - /tmp/install.sh - EOT -} - -# Legacy desktop app for backward compatibility -resource "coder_app" "cursor_desktop" { +resource "coder_app" "cursor" { agent_id = var.agent_id external = true - icon = var.icon - slug = "cursor-desktop" - display_name = "Cursor Desktop" - order = var.order != null ? var.order + 1 : null + icon = "/icon/cursor.svg" + slug = var.slug + display_name = var.display_name + order = var.order group = var.group url = join("", [ "cursor://coder.coder-remote/open", @@ -139,7 +67,7 @@ resource "coder_app" "cursor_desktop" { data.coder_workspace_owner.me.name, "&workspace=", data.coder_workspace.me.name, - var.folder != "/home/coder" ? join("", ["&folder=", var.folder]) : "", + var.folder != "" ? join("", ["&folder=", var.folder]) : "", var.open_recent ? "&openRecent" : "", "&url=", data.coder_workspace.me.access_url, @@ -147,7 +75,7 @@ resource "coder_app" "cursor_desktop" { ]) } -output "cursor_desktop_url" { - value = coder_app.cursor_desktop.url +output "cursor_url" { + value = coder_app.cursor.url description = "Cursor IDE Desktop URL." }