Skip to content
Open
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
12 changes: 12 additions & 0 deletions .icons/positron.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added registry/cytoshahar/.images/avatar.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions registry/cytoshahar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
display_name: "CytoShahar"
bio: "Data engineer by day, maker by night"
avatar: "./.images/avatar.jpeg"
github: "https://github.com/CytoShahar"
linkedin: "https://www.linkedin.com/in/shaharzrihen" # Optional
status: "community"
---

# Shahar Zrihen

Data engineer by day, maker by night
38 changes: 38 additions & 0 deletions registry/cytoshahar/modules/positron/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
display_name: Positron Desktop
description: Add a one-click button to launch Positron Desktop
icon: ../../../../.icons/positron.svg
verified: true
tags: [ide, positron]
---

# Positron Desktop

Add a button to open any workspace with a single click.

Uses the [Coder Remote VS Code Extension](https://github.com/coder/vscode-coder).

```tf
module "positron" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/positron/coder"
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source path is incorrect. It should be registry.coder.com/cytoshahar/positron/coder to match the actual module location in the registry/cytoshahar/modules/positron directory, not registry.coder.com/coder/positron/coder.

Copilot uses AI. Check for mistakes.
version = "1.0.0"
agent_id = coder_agent.example.id
}
```

## Examples

### Open in a specific directory

```tf
module "positron" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/positron/coder"
version = "1.1.1"
Comment on lines +31 to +32
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version mismatch in the example. The PR description indicates this is version 1.0.0, but the example shows version 1.1.1. Additionally, the source path should be registry.coder.com/cytoshahar/positron/coder to match the actual module location.

Suggested change
source = "registry.coder.com/coder/positron/coder"
version = "1.1.1"
source = "registry.coder.com/cytoshahar/positron/coder"
version = "1.0.0"

Copilot uses AI. Check for mistakes.
agent_id = coder_agent.example.id
folder = "/home/coder/project"
}
```

Based on the [Coder VS Code Desktop Module](https://github.com/coder/registry/tree/main/registry/coder/modules/vscode-desktop)
89 changes: 89 additions & 0 deletions registry/cytoshahar/modules/positron/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { describe, expect, it } from "bun:test";
import {
executeScriptInContainer,
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "~test";
Comment on lines +2 to +7
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import executeScriptInContainer.

Copilot uses AI. Check for mistakes.

describe("positron-desktop", 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.positron_url.value).toBe(
"positron://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 === "positron",
);

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.positron_url.value).toBe(
"positron://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.positron_url.value).toBe(
"positron://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.positron_url.value).toBe(
"positron://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.positron_url.value).toBe(
"positron://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 === "positron",
);

expect(coder_app).not.toBeNull();
expect(coder_app?.instances.length).toBe(1);
expect(coder_app?.instances[0].attributes.order).toBe(22);
});
});
74 changes: 74 additions & 0 deletions registry/cytoshahar/modules/positron/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
terraform {
required_version = ">= 1.0"

required_providers {
coder = {
source = "coder/coder"
version = ">= 2.5"
}
}
}

locals {
icon_url = "/icon/positron.svg"
}
Comment on lines +12 to +14
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local variable icon_url is defined but never used. The icon path is hardcoded directly on line 51. Either remove this unused local variable or replace the hardcoded value on line 51 with local.icon_url for consistency.

Copilot uses AI. Check for mistakes.

variable "agent_id" {
type = string
description = "The ID of a Coder agent."
}

variable "folder" {
type = string
description = "The folder to open in Positron."
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
}

variable "group" {
type = string
description = "The name of a group that this app belongs to."
default = null
}

data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

resource "coder_app" "positron" {
agent_id = var.agent_id
external = true
icon = "/icon/positron.svg"
slug = "positron"
display_name = "Positron Desktop"
order = var.order
group = var.group

url = join("", [
"positron://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 "positron_url" {
value = coder_app.positron.url
description = "Positron Desktop URL."
}
Loading