Completely restore cursor module to original state

- Undo all changes to existing cursor module
- Keep only the new cursor-cli module
- Ensure backward compatibility

Co-authored-by: matifali <10648092+matifali@users.noreply.github.com>
This commit is contained in:
blink-so[bot] 2025-08-08 11:46:56 +00:00
parent 6ce61c9acd
commit 2932fb482b
2 changed files with 51 additions and 140 deletions

View File

@ -12,37 +12,29 @@ describe("cursor", async () => {
agent_id: "foo", agent_id: "foo",
}); });
it("default output with CLI enabled", async () => { it("default output", async () => {
const state = await runTerraformApply(import.meta.dir, { const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo", agent_id: "foo",
}); });
expect(state.outputs.cursor_url.value).toBe(
// Check desktop app output "cursor://coder.coder-remote/open?owner=default&workspace=default&url=https://mydeployment.coder.com&token=$SESSION_TOKEN",
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",
); );
// 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( 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).not.toBeNull();
expect(coder_app?.instances.length).toBe(1); expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.order).toBeNull(); expect(coder_app?.instances[0].attributes.order).toBeNull();
}); });
it("adds custom folder", async () => { it("adds folder", async () => {
const state = await runTerraformApply(import.meta.dir, { const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo", agent_id: "foo",
folder: "/foo/bar", 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", "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", folder: "/foo/bar",
open_recent: "true", 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", "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, { const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo", agent_id: "foo",
open_recent: "true", 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=/home/coder&openRecent&url=https://mydeployment.coder.com&token=$SESSION_TOKEN", "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( 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).not.toBeNull();
expect(coder_app?.instances.length).toBe(1); expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.order).toBe(23); // order + 1 for desktop app expect(coder_app?.instances[0].attributes.order).toBe(22);
});
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();
}); });
}); });

View File

@ -4,7 +4,7 @@ terraform {
required_providers { required_providers {
coder = { coder = {
source = "coder/coder" source = "coder/coder"
version = ">= 2.7" version = ">= 2.5"
} }
} }
} }
@ -14,9 +14,17 @@ variable "agent_id" {
description = "The ID of a Coder agent." 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" { variable "order" {
type = number type = number
@ -30,108 +38,28 @@ variable "group" {
default = null default = null
} }
variable "icon" { variable "slug" {
type = string type = string
description = "The icon to use for the app." description = "The slug of the app."
default = "/icon/cursor.svg" default = "cursor"
} }
variable "folder" { variable "display_name" {
type = string type = string
description = "The folder to run Cursor in." description = "The display name of the app."
default = "/home/coder" default = "Cursor Desktop"
} }
variable "open_recent" { data "coder_workspace" "me" {}
type = bool data "coder_workspace_owner" "me" {}
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 "install_cursor_cli" { resource "coder_app" "cursor" {
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" {
agent_id = var.agent_id agent_id = var.agent_id
external = true external = true
icon = var.icon icon = "/icon/cursor.svg"
slug = "cursor-desktop" slug = var.slug
display_name = "Cursor Desktop" display_name = var.display_name
order = var.order != null ? var.order + 1 : null order = var.order
group = var.group group = var.group
url = join("", [ url = join("", [
"cursor://coder.coder-remote/open", "cursor://coder.coder-remote/open",
@ -139,7 +67,7 @@ resource "coder_app" "cursor_desktop" {
data.coder_workspace_owner.me.name, data.coder_workspace_owner.me.name,
"&workspace=", "&workspace=",
data.coder_workspace.me.name, data.coder_workspace.me.name,
var.folder != "/home/coder" ? join("", ["&folder=", var.folder]) : "", var.folder != "" ? join("", ["&folder=", var.folder]) : "",
var.open_recent ? "&openRecent" : "", var.open_recent ? "&openRecent" : "",
"&url=", "&url=",
data.coder_workspace.me.access_url, data.coder_workspace.me.access_url,
@ -147,7 +75,7 @@ resource "coder_app" "cursor_desktop" {
]) ])
} }
output "cursor_desktop_url" { output "cursor_url" {
value = coder_app.cursor_desktop.url value = coder_app.cursor.url
description = "Cursor IDE Desktop URL." description = "Cursor IDE Desktop URL."
} }