Skip to content

Commit da3c310

Browse files
authored
Merge branch 'main' into aider-tasks-agentapi-support
2 parents 78b9ebd + c270edf commit da3c310

File tree

8 files changed

+285
-6
lines changed

8 files changed

+285
-6
lines changed

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../AGENTS.md

.icons/electric-plug-emoji.svg

Lines changed: 1 addition & 0 deletions
Loading

AGENTS.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to AI coding assistants when working with code in this repository.
4+
5+
## Project Overview
6+
7+
The Coder Registry is a community-driven repository for Terraform modules and templates that extend Coder workspaces. It's organized with:
8+
9+
- **Modules**: Individual components and tools (IDEs, auth integrations, dev tools)
10+
- **Templates**: Complete workspace configurations for different platforms
11+
- **Namespaces**: Each contributor has their own namespace under `/registry/[namespace]/`
12+
13+
## Common Development Commands
14+
15+
### Formatting
16+
17+
```bash
18+
bun run fmt # Format all code (Prettier + Terraform)
19+
bun run fmt:ci # Check formatting (CI mode)
20+
```
21+
22+
### Testing
23+
24+
```bash
25+
# Test all modules with .tftest.hcl files
26+
bun run test
27+
28+
# Test specific module (from module directory)
29+
terraform init -upgrade
30+
terraform test -verbose
31+
32+
# Validate Terraform syntax
33+
./scripts/terraform_validate.sh
34+
```
35+
36+
### Module Creation
37+
38+
```bash
39+
# Generate new module scaffold
40+
./scripts/new_module.sh namespace/module-name
41+
```
42+
43+
### TypeScript Testing & Setup
44+
45+
The repository uses Bun for TypeScript testing with utilities:
46+
47+
- `test/test.ts` - Testing utilities for container management and Terraform operations
48+
- `setup.ts` - Test cleanup (removes .tfstate files and test containers)
49+
- Container-based testing with Docker for module validation
50+
51+
## Architecture & Organization
52+
53+
### Directory Structure
54+
55+
```
56+
registry/[namespace]/
57+
├── README.md # Contributor info with frontmatter
58+
├── .images/ # Namespace avatar (avatar.png/svg)
59+
├── modules/ # Individual components
60+
│ └── [module]/ # Each module has main.tf, README.md, tests
61+
└── templates/ # Complete workspace configs
62+
└── [template]/ # Each template has main.tf, README.md
63+
```
64+
65+
### Key Components
66+
67+
**Module Structure**: Each module contains:
68+
69+
- `main.tf` - Terraform implementation
70+
- `README.md` - Documentation with YAML frontmatter
71+
- `.tftest.hcl` - Terraform test files (required)
72+
- `run.sh` - Optional startup script
73+
74+
**Template Structure**: Each template contains:
75+
76+
- `main.tf` - Complete Coder template configuration
77+
- `README.md` - Documentation with YAML frontmatter
78+
- Additional configs, scripts as needed
79+
80+
### README Frontmatter Requirements
81+
82+
All modules/templates require YAML frontmatter:
83+
84+
```yaml
85+
---
86+
display_name: "Module Name"
87+
description: "Brief description"
88+
icon: "../../../../.icons/tool.svg"
89+
verified: false
90+
tags: ["tag1", "tag2"]
91+
---
92+
```
93+
94+
## Testing Requirements
95+
96+
### Module Testing
97+
98+
- Every module MUST have `.tftest.hcl` test files
99+
- Optional `main.test.ts` files for container-based testing or complex business logic validation
100+
- Tests use Docker containers with `--network=host` flag
101+
- Linux required for testing (Docker Desktop on macOS/Windows won't work)
102+
- Use Colima or OrbStack on macOS instead of Docker Desktop
103+
104+
### Test Utilities
105+
106+
The `test/test.ts` file provides:
107+
108+
- `runTerraformApply()` - Execute Terraform with variables
109+
- `executeScriptInContainer()` - Run coder_script resources in containers
110+
- `testRequiredVariables()` - Validate required variables
111+
- Container management functions
112+
113+
## Validation & Quality
114+
115+
### Automated Validation
116+
117+
The Go validation tool (`cmd/readmevalidation/`) checks:
118+
119+
- Repository structure integrity
120+
- Contributor README files
121+
- Module and template documentation
122+
- Frontmatter format compliance
123+
124+
### Versioning
125+
126+
Use semantic versioning for modules:
127+
128+
- **Patch** (1.2.3 → 1.2.4): Bug fixes
129+
- **Minor** (1.2.3 → 1.3.0): New features, adding inputs
130+
- **Major** (1.2.3 → 2.0.0): Breaking changes
131+
132+
## Dependencies & Tools
133+
134+
### Required Tools
135+
136+
- **Terraform** - Module development and testing
137+
- **Docker** - Container-based testing
138+
- **Bun** - JavaScript runtime for formatting/scripts
139+
- **Go 1.23+** - Validation tooling
140+
141+
### Development Dependencies
142+
143+
- Prettier with Terraform and shell plugins
144+
- TypeScript for test utilities
145+
- Various npm packages for documentation processing
146+
147+
## Workflow Notes
148+
149+
### Contributing Process
150+
151+
1. Create namespace (first-time contributors)
152+
2. Generate module/template files using scripts
153+
3. Implement functionality and tests
154+
4. Run formatting and validation
155+
5. Submit PR with appropriate template
156+
157+
### Testing Workflow
158+
159+
- All modules must pass `terraform test`
160+
- Use `bun run test` for comprehensive testing
161+
- Format code with `bun run fmt` before submission
162+
- Manual testing recommended for templates
163+
164+
### Namespace Management
165+
166+
- Each contributor gets unique namespace
167+
- Namespace avatar required (avatar.png/svg in .images/)
168+
- Namespace README with contributor info and frontmatter

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AGENTS.md
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
display_name: Externally Managed Workspace
3+
description: A template to provision externally managed resources as Coder workspaces
4+
icon: ../../../../.icons/electric-plug-emoji.svg
5+
verified: true
6+
tags: [external]
7+
---
8+
9+
# Externally Managed Workspace Template
10+
11+
> [!IMPORTANT]
12+
> External agents require a [Premium](https://coder.com/pricing) Coder license.
13+
14+
This template provides a minimal scaffolding for creating Coder workspaces that connect to externally provisioned compute resources.
15+
16+
Use this template as a starting point to build your own custom templates for scenarios where you need to connect to existing infrastructure.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
version = ">= 2.10"
6+
}
7+
}
8+
}
9+
10+
data "coder_parameter" "agent_config" {
11+
name = "agent_config"
12+
display_name = "Agent Configuration"
13+
description = "Select the operating system and architecture combination for the agent"
14+
type = "string"
15+
default = "linux-amd64"
16+
17+
option {
18+
name = "Linux AMD64"
19+
value = "linux-amd64"
20+
}
21+
option {
22+
name = "Linux ARM64"
23+
value = "linux-arm64"
24+
}
25+
option {
26+
name = "Linux ARMv7"
27+
value = "linux-armv7"
28+
}
29+
option {
30+
name = "Windows AMD64"
31+
value = "windows-amd64"
32+
}
33+
option {
34+
name = "Windows ARM64"
35+
value = "windows-arm64"
36+
}
37+
option {
38+
name = "macOS AMD64"
39+
value = "darwin-amd64"
40+
}
41+
option {
42+
name = "macOS ARM64 (Apple Silicon)"
43+
value = "darwin-arm64"
44+
}
45+
}
46+
47+
data "coder_workspace" "me" {}
48+
49+
locals {
50+
agent_config = split("-", data.coder_parameter.agent_config.value)
51+
agent_os = local.agent_config[0]
52+
agent_arch = local.agent_config[1]
53+
}
54+
55+
resource "coder_agent" "main" {
56+
arch = local.agent_arch
57+
os = local.agent_os
58+
}
59+
60+
resource "coder_external_agent" "main" {
61+
agent_id = coder_agent.main.id
62+
}
63+
64+
# Adds code-server
65+
# See all available modules at https://registry.coder.com/modules
66+
module "code-server" {
67+
count = data.coder_workspace.me.start_count
68+
source = "registry.coder.com/coder/code-server/coder"
69+
70+
# This ensures that the latest non-breaking version of the module gets downloaded, you can also pin the module version to prevent breaking changes in production.
71+
version = "~> 1.0"
72+
73+
agent_id = coder_agent.main.id
74+
}

registry/coder/modules/kiro/main.test.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,28 @@ describe("kiro", async () => {
9999
it("writes ~/.kiro/settings/mcp.json when mcp provided", async () => {
100100
const id = await runContainer("alpine");
101101
try {
102-
const mcp = JSON.stringify({ servers: { demo: { url: "http://localhost:1234" } } });
102+
const mcp = JSON.stringify({
103+
servers: { demo: { url: "http://localhost:1234" } },
104+
});
103105
const state = await runTerraformApply(import.meta.dir, {
104106
agent_id: "foo",
105107
mcp,
106108
});
107-
const script = findResourceInstance(state, "coder_script", "kiro_mcp").script;
109+
const script = findResourceInstance(
110+
state,
111+
"coder_script",
112+
"kiro_mcp",
113+
).script;
108114
const resp = await execContainer(id, ["sh", "-c", script]);
109115
if (resp.exitCode !== 0) {
110116
console.log(resp.stdout);
111117
console.log(resp.stderr);
112118
}
113119
expect(resp.exitCode).toBe(0);
114-
const content = await readFileContainer(id, "/root/.kiro/settings/mcp.json");
120+
const content = await readFileContainer(
121+
id,
122+
"/root/.kiro/settings/mcp.json",
123+
);
115124
expect(content).toBe(mcp);
116125
} finally {
117126
await removeContainer(id);

registry/coder/modules/windsurf/main.test.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,19 +94,28 @@ describe("windsurf", async () => {
9494
it("writes ~/.codeium/windsurf/mcp_config.json when mcp provided", async () => {
9595
const id = await runContainer("alpine");
9696
try {
97-
const mcp = JSON.stringify({ servers: { demo: { url: "http://localhost:1234" } } });
97+
const mcp = JSON.stringify({
98+
servers: { demo: { url: "http://localhost:1234" } },
99+
});
98100
const state = await runTerraformApply(import.meta.dir, {
99101
agent_id: "foo",
100102
mcp,
101103
});
102-
const script = findResourceInstance(state, "coder_script", "windsurf_mcp").script;
104+
const script = findResourceInstance(
105+
state,
106+
"coder_script",
107+
"windsurf_mcp",
108+
).script;
103109
const resp = await execContainer(id, ["sh", "-c", script]);
104110
if (resp.exitCode !== 0) {
105111
console.log(resp.stdout);
106112
console.log(resp.stderr);
107113
}
108114
expect(resp.exitCode).toBe(0);
109-
const content = await readFileContainer(id, "/root/.codeium/windsurf/mcp_config.json");
115+
const content = await readFileContainer(
116+
id,
117+
"/root/.codeium/windsurf/mcp_config.json",
118+
);
110119
expect(content).toBe(mcp);
111120
} finally {
112121
await removeContainer(id);

0 commit comments

Comments
 (0)