diff --git a/registry/coder/modules/cursor/main.tf b/registry/coder/modules/cursor/main.tf index 47d35b62..2688d7b1 100644 --- a/registry/coder/modules/cursor/main.tf +++ b/registry/coder/modules/cursor/main.tf @@ -1,12 +1,5 @@ terraform { required_version = ">= 1.0" - - required_providers { - coder = { - source = "coder/coder" - version = ">= 2.5" - } - } } variable "agent_id" { @@ -50,32 +43,24 @@ variable "display_name" { default = "Cursor Desktop" } -data "coder_workspace" "me" {} -data "coder_workspace_owner" "me" {} +module "cursor" { + # TODO: update this + source = "git::https://github.com/coder/registry.git//registry/coder/modules/vscode-desktop-core?ref=phorcys420/centralize-vscode-desktop" + + agent_id = var.agent_id -resource "coder_app" "cursor" { - agent_id = var.agent_id - external = true - 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", - "?owner=", - data.coder_workspace_owner.me.name, - "&workspace=", - data.coder_workspace.me.name, - var.folder != "" ? join("", ["&folder=", var.folder]) : "", - var.open_recent ? "&openRecent" : "", - "&url=", - data.coder_workspace.me.access_url, - "&token=$SESSION_TOKEN", - ]) + web_app_icon = "/icon/cursor.svg" + web_app_slug = var.slug + web_app_display_name = var.display_name + web_app_order = var.order + web_app_group = var.group + + folder = var.folder + open_recent = var.open_recent + protocol = "cursor" } output "cursor_url" { - value = coder_app.cursor.url + value = module.cursor.ide_uri description = "Cursor IDE Desktop URL." -} +} \ No newline at end of file diff --git a/registry/coder/modules/kiro/README.md b/registry/coder/modules/kiro/README.md index 732472cb..19a3d46c 100644 --- a/registry/coder/modules/kiro/README.md +++ b/registry/coder/modules/kiro/README.md @@ -36,16 +36,3 @@ module "kiro" { folder = "/home/coder/project" } ``` - -### Open with custom display name and order - -```tf -module "kiro" { - count = data.coder_workspace.me.start_count - source = "registry.coder.com/coder/kiro/coder" - version = "1.0.0" - agent_id = coder_agent.example.id - display_name = "Kiro AI IDE" - order = 1 -} -``` diff --git a/registry/coder/modules/kiro/main.tf b/registry/coder/modules/kiro/main.tf index a6a49948..7822c5a9 100644 --- a/registry/coder/modules/kiro/main.tf +++ b/registry/coder/modules/kiro/main.tf @@ -1,12 +1,5 @@ terraform { required_version = ">= 1.0" - - required_providers { - coder = { - source = "coder/coder" - version = ">= 2.5" - } - } } variable "agent_id" { @@ -38,44 +31,24 @@ variable "group" { default = null } -variable "slug" { - type = string - description = "The slug of the app." - default = "kiro" -} +module "kiro" { + # TODO: update this + source = "git::https://github.com/coder/registry.git//registry/coder/modules/vscode-desktop-core?ref=phorcys420/centralize-vscode-desktop" -variable "display_name" { - type = string - description = "The display name of the app." - default = "Kiro IDE" -} + agent_id = var.agent_id -data "coder_workspace" "me" {} -data "coder_workspace_owner" "me" {} + web_app_icon = "/icon/kiro.svg" + web_app_slug = "kiro" + web_app_display_name = "Kiro IDE" + web_app_order = var.order + web_app_group = var.group -resource "coder_app" "kiro" { - agent_id = var.agent_id - external = true - icon = "/icon/kiro.svg" - slug = var.slug - display_name = var.display_name - order = var.order - group = var.group - url = join("", [ - "kiro://coder.coder-remote/open", - "?owner=", - data.coder_workspace_owner.me.name, - "&workspace=", - data.coder_workspace.me.name, - var.folder != "" ? join("", ["&folder=", var.folder]) : "", - var.open_recent ? "&openRecent" : "", - "&url=", - data.coder_workspace.me.access_url, - "&token=$SESSION_TOKEN", - ]) + folder = var.folder + open_recent = var.open_recent + protocol = "kiro" } output "kiro_url" { - value = coder_app.kiro.url + value = module.kiro.ide_uri description = "Kiro IDE URL." -} +} \ No newline at end of file diff --git a/registry/coder/modules/vscode-desktop-core/README.md b/registry/coder/modules/vscode-desktop-core/README.md new file mode 100644 index 00000000..fd847a64 --- /dev/null +++ b/registry/coder/modules/vscode-desktop-core/README.md @@ -0,0 +1,33 @@ +--- +display_name: Coder VSCode Desktop Core +description: Building block for modules that need to link to an external VSCode-based IDE +icon: ../../../../.icons/coder.svg +verified: true +tags: [internal, library] +--- + +# VS Code Desktop Core + +> [!CAUTION] +> We do not recommend using this module directly. Instead, please consider using one of our [Desktop IDE modules](https://registry.coder.com/modules?search=tag%3Aide). + +The VSCode Desktop Core module is a building block for modules that need to expose access to VSCode-based IDEs. It is intended primarily for internal use by Coder to create modules for VSCode-based IDEs. + +```tf +module "vscode-desktop-core" { + source = "registry.coder.com/coder/vscode-desktop-core/coder" + version = "1.0.1" + + agent_id = var.agent_id + + web_app_icon = "/icon/code.svg" + web_app_slug = "vscode" + web_app_display_name = "VS Code Desktop" + web_app_order = var.order + web_app_group = var.group + + folder = var.folder + open_recent = var.open_recent + protocol = "vscode" +} +``` diff --git a/registry/coder/modules/vscode-desktop-core/main.test.ts b/registry/coder/modules/vscode-desktop-core/main.test.ts new file mode 100644 index 00000000..e7b01966 --- /dev/null +++ b/registry/coder/modules/vscode-desktop-core/main.test.ts @@ -0,0 +1,100 @@ +import { describe, expect, it } from "bun:test"; +import { + runTerraformApply, + runTerraformInit, + testRequiredVariables, +} from "~test"; + +// hardcoded coder_app name in main.tf +const appName = "vscode-desktop"; + +const defaultVariables = { + agent_id: "foo", + web_app_icon: "/icon/code.svg", + web_app_slug: "vscode", + web_app_display_name: "VS Code Desktop", + protocol: "vscode", +} + +describe("vscode-desktop-core", async () => { + await runTerraformInit(import.meta.dir); + + testRequiredVariables(import.meta.dir, defaultVariables); + + it("default output", async () => { + const state = await runTerraformApply(import.meta.dir, defaultVariables); + expect(state.outputs.ide_uri.value).toBe( + `${defaultVariables.protocol}://coder.coder-remote/open?owner=default&workspace=default&url=https://mydeployment.coder.com&token=$SESSION_TOKEN`, + ); + + const coder_app = state.resources.find( + (res) => res.type === "coder_app" && res.name === appName, + ); + + expect(coder_app).not.toBeNull(); + expect(coder_app?.instances.length).toBe(1); + expect(coder_app?.instances[0].attributes.order).toBeNull(); + }); + + it("adds folder", async () => { + const state = await runTerraformApply(import.meta.dir, { + folder: "/foo/bar", + + ...defaultVariables + }); + + expect(state.outputs.ide_uri.value).toBe( + `${defaultVariables.protocol}://coder.coder-remote/open?owner=default&workspace=default&folder=/foo/bar&url=https://mydeployment.coder.com&token=$SESSION_TOKEN`, + ); + }); + + it("adds folder and open_recent", async () => { + const state = await runTerraformApply(import.meta.dir, { + folder: "/foo/bar", + open_recent: "true", + + ...defaultVariables, + }); + expect(state.outputs.ide_uri.value).toBe( + `${defaultVariables.protocol}://coder.coder-remote/open?owner=default&workspace=default&folder=/foo/bar&openRecent&url=https://mydeployment.coder.com&token=$SESSION_TOKEN`, + ); + }); + + it("adds folder but not open_recent", async () => { + const state = await runTerraformApply(import.meta.dir, { + folder: "/foo/bar", + openRecent: "false", + + ...defaultVariables, + }); + expect(state.outputs.ide_uri.value).toBe( + `${defaultVariables.protocol}://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, { + open_recent: "true", + + ...defaultVariables, + }); + expect(state.outputs.ide_uri.value).toBe( + `${defaultVariables.protocol}://coder.coder-remote/open?owner=default&workspace=default&openRecent&url=https://mydeployment.coder.com&token=$SESSION_TOKEN`, + ); + }); + + it("expect order to be set", async () => { + const state = await runTerraformApply(import.meta.dir, { + web_app_order: "22", + ...defaultVariables + }); + + const coder_app = state.resources.find( + (res) => res.type === "coder_app" && res.name === appName, + ); + + expect(coder_app).not.toBeNull(); + expect(coder_app?.instances.length).toBe(1); + expect(coder_app?.instances[0].attributes.order).toBe(22); + }); +}); diff --git a/registry/coder/modules/vscode-desktop-core/main.tf b/registry/coder/modules/vscode-desktop-core/main.tf new file mode 100644 index 00000000..7e675712 --- /dev/null +++ b/registry/coder/modules/vscode-desktop-core/main.tf @@ -0,0 +1,105 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + coder = { + source = "coder/coder" + version = ">= 2.5" + } + } +} + +variable "agent_id" { + type = string + description = "The ID of a Coder agent." +} + +variable "folder" { + type = string + description = "The folder to open in the IDE." + default = "" +} + +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 "protocol" { + type = string + description = "The URI protocol the IDE." +} + +variable "web_app_icon" { + type = string + description = "The icon of the coder_app." +} + +variable "web_app_slug" { + type = string + description = "The slug of the coder_app." +} + +variable "web_app_display_name" { + type = string + description = "The display name of the coder_app." +} + +variable "web_app_order" { + type = number + description = "The order of the coder_app." + default = null +} + +variable "web_app_group" { + type = string + description = "The group of the coder_app." + default = null +} + +data "coder_workspace" "me" {} +data "coder_workspace_owner" "me" {} + +resource "coder_app" "vscode-desktop" { + agent_id = var.agent_id + external = true + + icon = var.web_app_icon + slug = var.web_app_slug + display_name = var.web_app_display_name + + order = var.web_app_order + group = var.web_app_group + + url = join("", [ + var.protocol, + "://coder.coder-remote/open", + "?owner=", + data.coder_workspace_owner.me.name, + "&workspace=", + data.coder_workspace.me.name, + var.folder != "" ? join("", ["&folder=", var.folder]) : "", + var.open_recent ? "&openRecent" : "", + "&url=", + data.coder_workspace.me.access_url, + "&token=$SESSION_TOKEN", + ]) + + /* + url = join("", [ + "vscode://coder.coder-remote/open", + "?owner=${data.coder_workspace_owner.me.name}", + "&workspace=${data.coder_workspace.me.name}", + var.folder != "" ? join("", ["&folder=", var.folder]) : "", + var.open_recent ? "&openRecent" : "", + "&url=${data.coder_workspace.me.access_url}", + "&token=$SESSION_TOKEN", + ]) + */ +} + +output "ide_uri" { + value = coder_app.vscode-desktop.url + description = "IDE URI." +} \ No newline at end of file diff --git a/registry/coder/modules/vscode-desktop/main.tf b/registry/coder/modules/vscode-desktop/main.tf index f93d14e3..e23d5c5c 100644 --- a/registry/coder/modules/vscode-desktop/main.tf +++ b/registry/coder/modules/vscode-desktop/main.tf @@ -1,12 +1,5 @@ terraform { required_version = ">= 1.0" - - required_providers { - coder = { - source = "coder/coder" - version = ">= 2.5" - } - } } variable "agent_id" { @@ -38,33 +31,24 @@ variable "group" { default = null } -data "coder_workspace" "me" {} -data "coder_workspace_owner" "me" {} +module "vscode" { + # TODO: update this + source = "git::https://github.com/coder/registry.git//registry/coder/modules/vscode-desktop-core?ref=phorcys420/centralize-vscode-desktop" + + agent_id = var.agent_id -resource "coder_app" "vscode" { - agent_id = var.agent_id - external = true - icon = "/icon/code.svg" - slug = "vscode" - display_name = "VS Code Desktop" - order = var.order - group = var.group + web_app_icon = "/icon/code.svg" + web_app_slug = "vscode" + web_app_display_name = "VS Code Desktop" + web_app_order = var.order + web_app_group = var.group - url = join("", [ - "vscode://coder.coder-remote/open", - "?owner=", - data.coder_workspace_owner.me.name, - "&workspace=", - data.coder_workspace.me.name, - var.folder != "" ? join("", ["&folder=", var.folder]) : "", - var.open_recent ? "&openRecent" : "", - "&url=", - data.coder_workspace.me.access_url, - "&token=$SESSION_TOKEN", - ]) + folder = var.folder + open_recent = var.open_recent + protocol = "vscode" } output "vscode_url" { - value = coder_app.vscode.url + value = module.vscode.ide_uri description = "VS Code Desktop URL." -} +} \ No newline at end of file diff --git a/registry/coder/modules/windsurf/main.tf b/registry/coder/modules/windsurf/main.tf index 2f9d02a5..8203fb4e 100644 --- a/registry/coder/modules/windsurf/main.tf +++ b/registry/coder/modules/windsurf/main.tf @@ -1,12 +1,5 @@ terraform { required_version = ">= 1.0" - - required_providers { - coder = { - source = "coder/coder" - version = ">= 2.5" - } - } } variable "agent_id" { @@ -16,7 +9,7 @@ variable "agent_id" { variable "folder" { type = string - description = "The folder to open in Cursor IDE." + description = "The folder to open in Windsurf Editor." default = "" } @@ -38,32 +31,24 @@ variable "group" { default = null } -data "coder_workspace" "me" {} -data "coder_workspace_owner" "me" {} +module "windsurf" { + # TODO: update this + source = "git::https://github.com/coder/registry.git//registry/coder/modules/vscode-desktop-core?ref=phorcys420/centralize-vscode-desktop" + + agent_id = var.agent_id -resource "coder_app" "windsurf" { - agent_id = var.agent_id - external = true - icon = "/icon/windsurf.svg" - slug = "windsurf" - display_name = "Windsurf Editor" - order = var.order - group = var.group - url = join("", [ - "windsurf://coder.coder-remote/open", - "?owner=", - data.coder_workspace_owner.me.name, - "&workspace=", - data.coder_workspace.me.name, - var.folder != "" ? join("", ["&folder=", var.folder]) : "", - var.open_recent ? "&openRecent" : "", - "&url=", - data.coder_workspace.me.access_url, - "&token=$SESSION_TOKEN", - ]) + web_app_icon = "/icon/windsurf.svg" + web_app_slug = "windsurf" + web_app_display_name = "Windsurf Editor" + web_app_order = var.order + web_app_group = var.group + + folder = var.folder + open_recent = var.open_recent + protocol = "windsurf" } output "windsurf_url" { - value = coder_app.windsurf.url + value = module.windsurf.ide_uri description = "Windsurf Editor URL." -} +} \ No newline at end of file