Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions .icons/kiro.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions registry/coder/modules/kiro/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
display_name: Kiro IDE
description: Add a one-click button to launch Kiro IDE
icon: ../../../../.icons/kiro.svg
maintainer_github: coder
verified: true
tags: [ide, kiro, ai, aws]
---

# Kiro IDE

Add a button to open any workspace with a single click in Kiro IDE.

Kiro is an AI-powered IDE from AWS that helps developers build from concept to production with spec-driven development, featuring AI agents, hooks, and steering files.

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

```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
}
```

## Examples

### Open in a specific directory

```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
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
}
```
93 changes: 93 additions & 0 deletions registry/coder/modules/kiro/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { describe, expect, it } from "bun:test";
import {
runTerraformApply,
runTerraformInit,
testRequiredVariables,
} from "~test";

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

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.kiro_url.value).toBe(
"kiro://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.kiro_url.value).toBe(
"kiro://coder.coder-remote/open?owner=default&workspace=default&folder=/foo/bar&openRecent&url=https://mydeployment.coder.com&token=$SESSION_TOKEN",
);
});

it("custom slug and display_name", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
slug: "kiro-ai",
display_name: "Kiro AI IDE",
});

const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "kiro",
);

expect(coder_app?.instances[0].attributes.slug).toBe("kiro-ai");
expect(coder_app?.instances[0].attributes.display_name).toBe("Kiro AI IDE");
});

it("sets order", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
order: "5",
});

const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "kiro",
);

expect(coder_app?.instances[0].attributes.order).toBe(5);
});

it("sets group", async () => {
const state = await runTerraformApply(import.meta.dir, {
agent_id: "foo",
group: "AI IDEs",
});

const coder_app = state.resources.find(
(res) => res.type === "coder_app" && res.name === "kiro",
);

expect(coder_app?.instances[0].attributes.group).toBe("AI IDEs");
});
});
81 changes: 81 additions & 0 deletions registry/coder/modules/kiro/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
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 Kiro 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 "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
}

variable "slug" {
type = string
description = "The slug of the app."
default = "kiro"
}

variable "display_name" {
type = string
description = "The display name of the app."
default = "Kiro IDE"
}

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

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",
])
}

output "kiro_url" {
value = coder_app.kiro.url
description = "Kiro IDE URL."
}