Merge 768fb366a3
into 4d2531548f
commit
a555b962da
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 287 KiB |
@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
display_name: Windsurf IDE
|
||||||
|
description: Add a one-click button to launch Windsurf IDE
|
||||||
|
icon: ../.icons/windsurf.svg
|
||||||
|
maintainer_github: coder
|
||||||
|
verified: true
|
||||||
|
tags: [ide, windsurf, helper]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Windsurf IDE
|
||||||
|
|
||||||
|
Add a button to open any workspace with a single click in Windsurf IDE.
|
||||||
|
|
||||||
|
Uses the [Coder Remote VS Code Extension](https://github.com/coder/vscode-coder).
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "windsurf" {
|
||||||
|
source = "registry.coder.com/modules/windsurf/coder"
|
||||||
|
version = "1.0.19"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Open in a specific directory
|
||||||
|
|
||||||
|
```tf
|
||||||
|
module "windsurf" {
|
||||||
|
source = "registry.coder.com/modules/windsurf/coder"
|
||||||
|
version = "1.0.19"
|
||||||
|
agent_id = coder_agent.example.id
|
||||||
|
folder = "/home/coder/project"
|
||||||
|
}
|
||||||
|
```
|
@ -0,0 +1,88 @@
|
|||||||
|
import { describe, expect, it } from "bun:test";
|
||||||
|
import {
|
||||||
|
runTerraformApply,
|
||||||
|
runTerraformInit,
|
||||||
|
testRequiredVariables,
|
||||||
|
} from "../test";
|
||||||
|
|
||||||
|
describe("windsurf", async () => {
|
||||||
|
await runTerraformInit(import.meta.dir);
|
||||||
|
|
||||||
|
testRequiredVariables(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
});
|
||||||
|
|
||||||
|
it("default output", async () => {
|
||||||
|
const state = await runTerraformApply(import.meta.dir, {
|
||||||
|
agent_id: "foo",
|
||||||
|
});
|
||||||
|
expect(state.outputs.windsurf_url.value).toBe(
|
||||||
|
"windsurf://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 === "windsurf",
|
||||||
|
);
|
||||||
|
|
||||||
|
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, {
|
||||||
|
agent_id: "foo",
|
||||||
|
folder: "/foo/bar",
|
||||||
|
});
|
||||||
|
expect(state.outputs.windsurf_url.value).toBe(
|
||||||
|
"windsurf://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, {
|
||||||
|
agent_id: "foo",
|
||||||
|
folder: "/foo/bar",
|
||||||
|
open_recent: "true",
|
||||||
|
});
|
||||||
|
expect(state.outputs.windsurf_url.value).toBe(
|
||||||
|
"windsurf://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, {
|
||||||
|
agent_id: "foo",
|
||||||
|
folder: "/foo/bar",
|
||||||
|
openRecent: "false",
|
||||||
|
});
|
||||||
|
expect(state.outputs.windsurf_url.value).toBe(
|
||||||
|
"windsurf://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.windsurf_url.value).toBe(
|
||||||
|
"windsurf://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, {
|
||||||
|
agent_id: "foo",
|
||||||
|
order: "22",
|
||||||
|
});
|
||||||
|
|
||||||
|
const coder_app = state.resources.find(
|
||||||
|
(res) => res.type === "coder_app" && res.name === "windsurf",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(coder_app).not.toBeNull();
|
||||||
|
expect(coder_app?.instances.length).toBe(1);
|
||||||
|
expect(coder_app?.instances[0].attributes.order).toBe(22);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,62 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
coder = {
|
||||||
|
source = "coder/coder"
|
||||||
|
version = ">= 0.23"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "agent_id" {
|
||||||
|
type = string
|
||||||
|
description = "The ID of a Coder agent."
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "folder" {
|
||||||
|
type = string
|
||||||
|
description = "The folder to open in Windsurf."
|
||||||
|
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 "order" {
|
||||||
|
type = number
|
||||||
|
description = "The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order)."
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
data "coder_workspace" "me" {}
|
||||||
|
data "coder_workspace_owner" "me" {}
|
||||||
|
|
||||||
|
resource "coder_app" "windsurf" {
|
||||||
|
agent_id = var.agent_id
|
||||||
|
external = true
|
||||||
|
icon = "/icon/windsurf.svg"
|
||||||
|
slug = "windsurf"
|
||||||
|
display_name = "Windsurf Desktop"
|
||||||
|
order = var.order
|
||||||
|
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",
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
output "windsurf_url" {
|
||||||
|
value = coder_app.windsurf.url
|
||||||
|
description = "Windsurf Desktop URL."
|
||||||
|
}
|
Loading…
Reference in New Issue