mirror of
https://github.com/coder/registry.git
synced 2026-06-03 04:58:15 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0021a9fe7d | |||
| 70ca76e86d | |||
| 7c4ef92c8c | |||
| 7b84d916e1 | |||
| dd412fbf34 | |||
| faff2be207 | |||
| 6acded53f6 | |||
| f3c24af1db | |||
| 143656017e | |||
| 88a0ac840f | |||
| 5f3a559e83 | |||
| b4c162d281 | |||
| e58fd5d5da |
@@ -82,7 +82,8 @@ create_incident() {
|
||||
# Function to check for existing unresolved incidents
|
||||
check_existing_incident() {
|
||||
# Fetch the latest incidents with status not equal to "RESOLVED"
|
||||
local unresolved_incidents=$(curl -s -X GET "https://api.instatus.com/v1/$INSTATUS_PAGE_ID/incidents" \
|
||||
local unresolved_incidents
|
||||
unresolved_incidents=$(curl -s -X GET "https://api.instatus.com/v1/$INSTATUS_PAGE_ID/incidents" \
|
||||
-H "Authorization: Bearer $INSTATUS_API_KEY" \
|
||||
-H "Content-Type: application/json" | jq -r '.incidents[] | select(.status != "RESOLVED") | .id')
|
||||
|
||||
|
||||
@@ -70,21 +70,38 @@ update_readme_version() {
|
||||
if grep -q "source.*${module_source}" "$readme_path"; then
|
||||
echo "Updating version references for $namespace/$module_name in $readme_path"
|
||||
awk -v module_source="$module_source" -v new_version="$new_version" '
|
||||
/source.*=.*/ {
|
||||
if ($0 ~ module_source) {
|
||||
in_target_module = 1
|
||||
} else {
|
||||
in_target_module = 0
|
||||
}
|
||||
/^[[:space:]]*module[[:space:]]/ {
|
||||
in_module_block = 1
|
||||
module_content = $0 "\n"
|
||||
module_has_target_source = 0
|
||||
next
|
||||
}
|
||||
/^[[:space:]]*version[[:space:]]*=/ {
|
||||
if (in_target_module) {
|
||||
match($0, /^[[:space]]*/
|
||||
indent = substr($0, 1, RLENGTH)
|
||||
print indent "version = \"" new_version "\""
|
||||
in_target_module = 0
|
||||
in_module_block {
|
||||
module_content = module_content $0 "\n"
|
||||
if ($0 ~ /source.*=/ && $0 ~ module_source) {
|
||||
module_has_target_source = 1
|
||||
}
|
||||
if ($0 ~ /^[[:space:]]*}[[:space:]]*$/) {
|
||||
in_module_block = 0
|
||||
if (module_has_target_source) {
|
||||
num_lines = split(module_content, lines, "\n")
|
||||
for (i = 1; i <= num_lines; i++) {
|
||||
line = lines[i]
|
||||
if (line ~ /^[[:space:]]*version[[:space:]]*=/) {
|
||||
match(line, /^[[:space:]]*/)
|
||||
indent = substr(line, 1, RLENGTH)
|
||||
printf "%sversion = \"%s\"\n", indent, new_version
|
||||
} else {
|
||||
print line
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf "%s", module_content
|
||||
}
|
||||
module_content = ""
|
||||
next
|
||||
}
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
' "$readme_path" > "${readme_path}.tmp" && mv "${readme_path}.tmp" "$readme_path"
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run check.sh
|
||||
run: |
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Detect changed files
|
||||
uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
@@ -29,8 +29,11 @@ jobs:
|
||||
- 'scripts/ts_test_auto.sh'
|
||||
- 'scripts/terraform_test_all.sh'
|
||||
- 'scripts/terraform_validate.sh'
|
||||
- 'scripts/shellcheck_validate.sh'
|
||||
modules:
|
||||
- 'registry/**/modules/**'
|
||||
shell:
|
||||
- '**/*.sh'
|
||||
all:
|
||||
- '**'
|
||||
- name: Set up Terraform
|
||||
@@ -64,12 +67,20 @@ jobs:
|
||||
SHARED_CHANGED: ${{ steps.filter.outputs.shared }}
|
||||
MODULE_CHANGED_FILES: ${{ steps.filter.outputs.modules_files }}
|
||||
run: bun terraform-validate
|
||||
- name: Run ShellCheck
|
||||
env:
|
||||
ALL_CHANGED_FILES: ${{ steps.filter.outputs.all_files }}
|
||||
SHARED_CHANGED: ${{ steps.filter.outputs.shared }}
|
||||
SHELL_CHANGED_FILES: ${{ steps.filter.outputs.shell_files }}
|
||||
run: bun shellcheck
|
||||
- name: Validate set -u ordering
|
||||
run: ./scripts/validate_set_u_order.sh
|
||||
validate-style:
|
||||
name: Check for typos and unformatted code
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
@@ -93,11 +104,11 @@ jobs:
|
||||
needs: validate-style
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.23.2"
|
||||
go-version: "1.24.0"
|
||||
- name: Validate contributors
|
||||
run: go build ./cmd/readmevalidation && ./readmevalidation
|
||||
- name: Remove build file artifact
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Authenticate with Google Cloud
|
||||
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093
|
||||
with:
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg width='240' height='300' viewBox='0 0 240 300' fill='none' xmlns='http://www.w3.org/2000/svg'><g clip-path='url(#clip0_1401_86283)'><mask id='mask0_1401_86283' style='mask-type:luminance' maskUnits='userSpaceOnUse' x='0' y='0' width='240' height='300'><path d='M240 0H0V300H240V0Z' fill='white'/></mask><g mask='url(#mask0_1401_86283)'><path d='M180 240H60V120H180V240Z' fill='#4B4646'/><path d='M180 60H60V240H180V60ZM240 300H0V0H240V300Z' fill='#F1ECEC'/></g></g><defs><clipPath id='clip0_1401_86283'><rect width='240' height='300' fill='white'/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 577 B |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 440 440">
|
||||
<g id="Layer_6" data-name="Layer 6">
|
||||
<rect x="12" y="12" width="416" height="416" rx="103" ry="103" fill="#3a78b1" stroke-width="0"/>
|
||||
</g>
|
||||
<g id="Layer_8" data-name="Layer 8">
|
||||
<path d="M83.6,373.6v-178.6c0-63,52.4-143.7,142.7-143.7s144.1,69.7,144.1,141.1c0,122.6-116.6,143.1-116.6,143.1,0,0,7.2-11.5,7.2-29.5s-8-28-8-28c0,0,60-16,60-87s-53-83-86-83c-57,0-88.3,48.5-88.3,84.3v181.9c0,25.9-17.5,23.9-17.5,23.9h-19.2s-18.4,0-18.4-24.4Z" fill="#fff" stroke-width="0"/>
|
||||
</g>
|
||||
<g id="Layer_9" data-name="Layer 9">
|
||||
<circle cx="204.9" cy="306.6" r="48" fill="#fff" stroke-width="0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 727 B |
@@ -0,0 +1,22 @@
|
||||
# ShellCheck configuration for Coder Registry
|
||||
# https://www.shellcheck.net/wiki/
|
||||
|
||||
# Set default shell dialect to bash (most scripts use bash)
|
||||
shell=bash
|
||||
|
||||
# Disable checks that conflict with Terraform templating syntax
|
||||
# Many scripts use Terraform's templatefile() function with $${VAR} escape syntax
|
||||
disable=SC2154 # Variable is referenced but not assigned (injected by Terraform)
|
||||
disable=SC2034 # Variable appears unused (used via $${VAR} syntax)
|
||||
disable=SC1083 # Literal braces (Terraform's $${VAR} escape syntax)
|
||||
disable=SC2193 # Comparison arguments never equal (Terraform interpolation)
|
||||
disable=SC2125 # Brace expansion/globs in assignments (Terraform syntax)
|
||||
disable=SC2157 # Argument to -n/-z is always true/false (Terraform $${VAR} syntax)
|
||||
disable=SC2066 # Loop will only run once (Terraform $${VAR} array syntax)
|
||||
|
||||
# Disable checks that conflict with intentional patterns
|
||||
disable=SC2076 # Quoted regex in =~ (intentional literal string match, not regex, for array membership checks)
|
||||
|
||||
# Enable all optional checks for thorough analysis
|
||||
enable=all
|
||||
|
||||
@@ -39,7 +39,7 @@ module "cursor" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/cursor/coder"
|
||||
version = "1.0.19"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "registry",
|
||||
@@ -13,6 +12,7 @@
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-sh": "^0.18.0",
|
||||
"prettier-plugin-terraform-formatter": "^1.2.1",
|
||||
"shellcheck": "^4.1.0",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.8.3",
|
||||
@@ -20,54 +20,296 @@
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@borewit/text-codec": ["@borewit/text-codec@0.1.1", "", {}, "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA=="],
|
||||
|
||||
"@felipecrs/decompress-tarxz": ["@felipecrs/decompress-tarxz@5.0.4", "", { "dependencies": { "@xhmikosr/decompress-tar": "^8.1.0", "file-type": "^20.5.0", "is-stream": "^2.0.1", "xz-decompress": "^0.2.3" } }, "sha512-a+nAnDsiUA84Sy/a+FKYJtjOjFvNtW8Jcbi3NwE8kJKPpYAxINFLYsC9mev9/wngiNEBA3jfHn0qNFwICeZNJw=="],
|
||||
|
||||
"@reteps/dockerfmt": ["@reteps/dockerfmt@0.3.6", "", {}, "sha512-Tb5wIMvBf/nLejTQ61krK644/CEMB/cpiaIFXqGApfGqO3GwcR3qnI0DbmkFVCl2OyEp8LnLX3EkucoL0+tbFg=="],
|
||||
|
||||
"@tokenizer/inflate": ["@tokenizer/inflate@0.2.7", "", { "dependencies": { "debug": "^4.4.0", "fflate": "^0.8.2", "token-types": "^6.0.0" } }, "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg=="],
|
||||
|
||||
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.2.21", "", { "dependencies": { "bun-types": "1.2.21" } }, "sha512-NiDnvEqmbfQ6dmZ3EeUO577s4P5bf4HCTXtI6trMc6f6RzirY5IrF3aIookuSpyslFzrnvv2lmEWv5HyC1X79A=="],
|
||||
|
||||
"@types/node": ["@types/node@24.0.14", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw=="],
|
||||
|
||||
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
|
||||
|
||||
"@xhmikosr/decompress-tar": ["@xhmikosr/decompress-tar@8.1.0", "", { "dependencies": { "file-type": "^20.5.0", "is-stream": "^2.0.1", "tar-stream": "^3.1.7" } }, "sha512-m0q8x6lwxenh1CrsTby0Jrjq4vzW/QU1OLhTHMQLEdHpmjR1lgahGz++seZI0bXF3XcZw3U3xHfqZSz+JPP2Gg=="],
|
||||
|
||||
"@xhmikosr/decompress-unzip": ["@xhmikosr/decompress-unzip@7.1.0", "", { "dependencies": { "file-type": "^20.5.0", "get-stream": "^6.0.1", "yauzl": "^3.1.2" } }, "sha512-oqTYAcObqTlg8owulxFTqiaJkfv2SHsxxxz9Wg4krJAHVzGWlZsU8tAB30R6ow+aHrfv4Kub6WQ8u04NWVPUpA=="],
|
||||
|
||||
"argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||
|
||||
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
||||
|
||||
"b4a": ["b4a@1.7.3", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q=="],
|
||||
|
||||
"bare-events": ["bare-events@2.8.0", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-AOhh6Bg5QmFIXdViHbMc2tLDsBIRxdkIaIddPslJF9Z5De3APBScuqGP2uThXnIpqFrgoxMNC6km7uXNIMLHXA=="],
|
||||
|
||||
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||
|
||||
"bl": ["bl@1.2.3", "", { "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww=="],
|
||||
|
||||
"boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="],
|
||||
|
||||
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||
|
||||
"buffer-alloc": ["buffer-alloc@1.2.0", "", { "dependencies": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" } }, "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow=="],
|
||||
|
||||
"buffer-alloc-unsafe": ["buffer-alloc-unsafe@1.1.0", "", {}, "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg=="],
|
||||
|
||||
"buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
||||
|
||||
"buffer-fill": ["buffer-fill@1.0.0", "", {}, "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.21", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-sa2Tj77Ijc/NTLS0/Odjq/qngmEPZfbfnOERi0KRUYhT9R8M4VBioWVmMWE5GrYbKMc+5lVybXygLdibHaqVqw=="],
|
||||
|
||||
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
|
||||
|
||||
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||
|
||||
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
||||
|
||||
"commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
|
||||
|
||||
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"decompress": ["decompress@4.2.1", "", { "dependencies": { "decompress-tar": "^4.0.0", "decompress-tarbz2": "^4.0.0", "decompress-targz": "^4.0.0", "decompress-unzip": "^4.0.1", "graceful-fs": "^4.1.10", "make-dir": "^1.0.0", "pify": "^2.3.0", "strip-dirs": "^2.0.0" } }, "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ=="],
|
||||
|
||||
"decompress-tar": ["decompress-tar@4.1.1", "", { "dependencies": { "file-type": "^5.2.0", "is-stream": "^1.1.0", "tar-stream": "^1.5.2" } }, "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ=="],
|
||||
|
||||
"decompress-tarbz2": ["decompress-tarbz2@4.1.1", "", { "dependencies": { "decompress-tar": "^4.1.0", "file-type": "^6.1.0", "is-stream": "^1.1.0", "seek-bzip": "^1.0.5", "unbzip2-stream": "^1.0.9" } }, "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A=="],
|
||||
|
||||
"decompress-targz": ["decompress-targz@4.1.1", "", { "dependencies": { "decompress-tar": "^4.1.1", "file-type": "^5.2.0", "is-stream": "^1.1.0" } }, "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w=="],
|
||||
|
||||
"decompress-unzip": ["decompress-unzip@4.0.1", "", { "dependencies": { "file-type": "^3.8.0", "get-stream": "^2.2.0", "pify": "^2.3.0", "yauzl": "^2.4.2" } }, "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw=="],
|
||||
|
||||
"dedent": ["dedent@1.6.0", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA=="],
|
||||
|
||||
"define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
|
||||
|
||||
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
||||
|
||||
"detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="],
|
||||
|
||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||
|
||||
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
||||
|
||||
"envalid": ["envalid@8.1.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-OT6+qVhKVyCidaGoXflb2iK1tC8pd0OV2Q+v9n33wNhUJ+lus+rJobUj4vJaQBPxPZ0vYrPGuxdrenyCAIJcow=="],
|
||||
|
||||
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||
|
||||
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||
|
||||
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
||||
|
||||
"es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
|
||||
|
||||
"events-universal": ["events-universal@1.0.1", "", { "dependencies": { "bare-events": "^2.7.0" } }, "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw=="],
|
||||
|
||||
"extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="],
|
||||
|
||||
"fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
|
||||
|
||||
"fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="],
|
||||
|
||||
"fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="],
|
||||
|
||||
"file-type": ["file-type@20.5.0", "", { "dependencies": { "@tokenizer/inflate": "^0.2.6", "strtok3": "^10.2.0", "token-types": "^6.0.0", "uint8array-extras": "^1.4.0" } }, "sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg=="],
|
||||
|
||||
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
||||
|
||||
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
|
||||
|
||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||
|
||||
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
||||
|
||||
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
|
||||
|
||||
"global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", "matcher": "^3.0.0", "roarr": "^2.15.3", "semver": "^7.3.2", "serialize-error": "^7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="],
|
||||
|
||||
"globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="],
|
||||
|
||||
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="],
|
||||
|
||||
"has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="],
|
||||
|
||||
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
||||
|
||||
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
||||
|
||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||
|
||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
|
||||
"is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
|
||||
|
||||
"is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="],
|
||||
|
||||
"is-natural-number": ["is-natural-number@4.0.1", "", {}, "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ=="],
|
||||
|
||||
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
||||
|
||||
"is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="],
|
||||
|
||||
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
|
||||
|
||||
"js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
|
||||
|
||||
"json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="],
|
||||
|
||||
"kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="],
|
||||
|
||||
"make-dir": ["make-dir@1.3.0", "", { "dependencies": { "pify": "^3.0.0" } }, "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ=="],
|
||||
|
||||
"marked": ["marked@16.2.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-LbbTuye+0dWRz2TS9KJ7wsnD4KAtpj0MVkWc90XvBa6AslXsT0hTBVH5k32pcSyHH1fst9XEFJunXHktVy0zlg=="],
|
||||
|
||||
"matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="],
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
||||
|
||||
"object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="],
|
||||
|
||||
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
|
||||
|
||||
"pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
|
||||
|
||||
"pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
|
||||
|
||||
"pinkie": ["pinkie@2.0.4", "", {}, "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg=="],
|
||||
|
||||
"pinkie-promise": ["pinkie-promise@2.0.1", "", { "dependencies": { "pinkie": "^2.0.0" } }, "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw=="],
|
||||
|
||||
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
||||
|
||||
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||
|
||||
"prettier-plugin-sh": ["prettier-plugin-sh@0.18.0", "", { "dependencies": { "@reteps/dockerfmt": "^0.3.6", "sh-syntax": "^0.5.8" }, "peerDependencies": { "prettier": "^3.6.0" } }, "sha512-cW1XL27FOJQ/qGHOW6IHwdCiNWQsAgK+feA8V6+xUTaH0cD3Mh+tFAtBvEEWvuY6hTDzRV943Fzeii+qMOh7nQ=="],
|
||||
|
||||
"prettier-plugin-terraform-formatter": ["prettier-plugin-terraform-formatter@1.2.1", "", { "peerDependencies": { "prettier": ">= 1.16.0" }, "optionalPeers": ["prettier"] }, "sha512-rdzV61Bs/Ecnn7uAS/vL5usTX8xUWM+nQejNLZxt3I1kJH5WSeLEmq7LYu1wCoEQF+y7Uv1xGvPRfl3lIe6+tA=="],
|
||||
|
||||
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
||||
|
||||
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||
|
||||
"roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", "globalthis": "^1.0.1", "json-stringify-safe": "^5.0.1", "semver-compare": "^1.0.0", "sprintf-js": "^1.1.2" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="],
|
||||
|
||||
"safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
||||
|
||||
"section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="],
|
||||
|
||||
"seek-bzip": ["seek-bzip@1.0.6", "", { "dependencies": { "commander": "^2.8.1" }, "bin": { "seek-bunzip": "bin/seek-bunzip", "seek-table": "bin/seek-bzip-table" } }, "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ=="],
|
||||
|
||||
"semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||
|
||||
"semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="],
|
||||
|
||||
"serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="],
|
||||
|
||||
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
|
||||
|
||||
"sh-syntax": ["sh-syntax@0.5.8", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-JfVoxf4FxQI5qpsPbkHhZo+n6N9YMJobyl4oGEUBb/31oQYlgTjkXQD8PBiafS2UbWoxrTO0Z5PJUBXEPAG1Zw=="],
|
||||
|
||||
"shellcheck": ["shellcheck@4.1.0", "", { "dependencies": { "@felipecrs/decompress-tarxz": "5.0.4", "@xhmikosr/decompress-unzip": "7.1.0", "decompress": "4.2.1", "envalid": "8.1.0", "global-agent": "3.0.0" }, "bin": { "shellcheck": "bin/shellcheck.js" } }, "sha512-8143z6YGO4+Puwp9Ghn/g7+QxllSKlXaZSm3HXfvQXUfRXhM5P8TPORRHBBlyobl9BnniVne+d1Ff6RgNiccsQ=="],
|
||||
|
||||
"sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
|
||||
|
||||
"streamx": ["streamx@2.23.0", "", { "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" } }, "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg=="],
|
||||
|
||||
"string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||
|
||||
"strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="],
|
||||
|
||||
"strip-dirs": ["strip-dirs@2.1.0", "", { "dependencies": { "is-natural-number": "^4.0.1" } }, "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g=="],
|
||||
|
||||
"strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
|
||||
|
||||
"tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
|
||||
|
||||
"text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
|
||||
|
||||
"through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="],
|
||||
|
||||
"to-buffer": ["to-buffer@1.2.2", "", { "dependencies": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", "typed-array-buffer": "^1.0.3" } }, "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw=="],
|
||||
|
||||
"token-types": ["token-types@6.1.1", "", { "dependencies": { "@borewit/text-codec": "^0.1.0", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="],
|
||||
|
||||
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
|
||||
|
||||
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
|
||||
|
||||
"unbzip2-stream": ["unbzip2-stream@1.4.3", "", { "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" } }, "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg=="],
|
||||
|
||||
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
|
||||
|
||||
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||
|
||||
"which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="],
|
||||
|
||||
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
||||
|
||||
"xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
|
||||
|
||||
"xz-decompress": ["xz-decompress@0.2.3", "", {}, "sha512-O8v6HG8T0PrKBcpyWA13GkSYWFvncwzuzcLx5A7++l3HsE3atmoetXjIxrZ/JV/nbvSZ7WS4+3XvREZuVn+rEA=="],
|
||||
|
||||
"yauzl": ["yauzl@3.2.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "pend": "~1.2.0" } }, "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w=="],
|
||||
|
||||
"decompress-tar/file-type": ["file-type@5.2.0", "", {}, "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ=="],
|
||||
|
||||
"decompress-tar/is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="],
|
||||
|
||||
"decompress-tar/tar-stream": ["tar-stream@1.6.2", "", { "dependencies": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", "end-of-stream": "^1.0.0", "fs-constants": "^1.0.0", "readable-stream": "^2.3.0", "to-buffer": "^1.1.1", "xtend": "^4.0.0" } }, "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A=="],
|
||||
|
||||
"decompress-tarbz2/file-type": ["file-type@6.2.0", "", {}, "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg=="],
|
||||
|
||||
"decompress-tarbz2/is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="],
|
||||
|
||||
"decompress-targz/file-type": ["file-type@5.2.0", "", {}, "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ=="],
|
||||
|
||||
"decompress-targz/is-stream": ["is-stream@1.1.0", "", {}, "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="],
|
||||
|
||||
"decompress-unzip/file-type": ["file-type@3.9.0", "", {}, "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA=="],
|
||||
|
||||
"decompress-unzip/get-stream": ["get-stream@2.3.1", "", { "dependencies": { "object-assign": "^4.0.1", "pinkie-promise": "^2.0.0" } }, "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA=="],
|
||||
|
||||
"decompress-unzip/yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="],
|
||||
|
||||
"make-dir/pify": ["pify@3.0.0", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="],
|
||||
|
||||
"roarr/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
|
||||
|
||||
"to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
|
||||
|
||||
"to-buffer/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ Run the [Goose](https://block.github.io/goose/) agent in your workspace to gener
|
||||
module "goose" {
|
||||
source = "registry.coder.com/coder/goose/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder"
|
||||
install_goose = true
|
||||
goose_version = "v1.0.16"
|
||||
@@ -40,7 +40,7 @@ module "coder-login" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/coder-login/coder"
|
||||
version = "1.0.15"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
|
||||
variable "anthropic_api_key" {
|
||||
@@ -82,7 +82,7 @@ module "goose" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/goose/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder"
|
||||
install_goose = true
|
||||
goose_version = "v1.0.16"
|
||||
@@ -110,7 +110,7 @@ Run Goose as a standalone app in your workspace. This will install Goose and run
|
||||
module "goose" {
|
||||
source = "registry.coder.com/coder/goose/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder"
|
||||
install_goose = true
|
||||
goose_version = "v1.0.16"
|
||||
|
||||
@@ -31,7 +31,7 @@ module "MODULE_NAME" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/NAMESPACE/MODULE_NAME/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
extensions = [
|
||||
"dracula-theme.theme-dracula"
|
||||
]
|
||||
@@ -49,7 +49,7 @@ module "MODULE_NAME" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/NAMESPACE/MODULE_NAME/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
extensions = ["dracula-theme.theme-dracula"]
|
||||
settings = {
|
||||
"workbench.colorTheme" = "Dracula"
|
||||
@@ -65,7 +65,7 @@ Run code-server in the background, don't fetch it from GitHub:
|
||||
module "MODULE_NAME" {
|
||||
source = "registry.coder.com/NAMESPACE/MODULE_NAME/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
offline = true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module coder.com/coder-registry
|
||||
|
||||
go 1.23.2
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
cdr.dev/slog v1.6.1
|
||||
@@ -20,7 +20,7 @@ require (
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
go.opentelemetry.io/otel v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/term v0.29.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/term v0.37.0 // indirect
|
||||
)
|
||||
|
||||
@@ -51,17 +51,17 @@ go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiM
|
||||
go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4=
|
||||
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
|
||||
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e h1:xIXmWJ303kJCuogpj0bHq+dcjcZHU+XFyc1I0Yl9cRg=
|
||||
|
||||
+3
-1
@@ -6,6 +6,7 @@
|
||||
"terraform-validate": "./scripts/terraform_validate.sh",
|
||||
"tftest": "./scripts/terraform_test_all.sh",
|
||||
"tstest": "./scripts/ts_test_auto.sh",
|
||||
"shellcheck": "./scripts/shellcheck_validate.sh",
|
||||
"update-version": "./update-version.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -16,7 +17,8 @@
|
||||
"marked": "^16.2.0",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-sh": "^0.18.0",
|
||||
"prettier-plugin-terraform-formatter": "^1.2.1"
|
||||
"prettier-plugin-terraform-formatter": "^1.2.1",
|
||||
"shellcheck": "^4.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.8.3"
|
||||
|
||||
@@ -17,7 +17,7 @@ It can be served on a Coder subdomain for easy access, or on `localhost` if you
|
||||
module "pgadmin" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/AJ0070/pgadmin/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -14,8 +14,8 @@ Launches RustDesk within your workspace with a virtual display to provide remote
|
||||
module "rustdesk" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/BenraouaneSoufiane/rustdesk/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -41,8 +41,8 @@ module "rustdesk" {
|
||||
module "rustdesk" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/BenraouaneSoufiane/rustdesk/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
rustdesk_password = "mycustompass"
|
||||
xvfb_resolution = "1920x1080x24"
|
||||
rustdesk_version = "1.4.1"
|
||||
|
||||
@@ -15,7 +15,7 @@ up a default or custom tmux configuration with session save/restore capabilities
|
||||
```tf
|
||||
module "tmux" {
|
||||
source = "registry.coder.com/anomaly/tmux/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -39,7 +39,7 @@ module "tmux" {
|
||||
```tf
|
||||
module "tmux" {
|
||||
source = "registry.coder.com/anomaly/tmux/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
agent_id = coder_agent.example.id
|
||||
tmux_config = "" # Optional: custom tmux.conf content
|
||||
save_interval = 1 # Optional: save interval in minutes
|
||||
@@ -78,7 +78,7 @@ This module can provision multiple tmux sessions, each as a separate app in the
|
||||
```tf
|
||||
module "tmux" {
|
||||
source = "registry.coder.com/anomaly/tmux/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
agent_id = var.agent_id
|
||||
sessions = ["default", "dev", "anomaly"]
|
||||
tmux_config = <<-EOT
|
||||
|
||||
@@ -144,7 +144,7 @@ main() {
|
||||
printf "$${BOLD}✅ tmux setup complete! \n\n"
|
||||
|
||||
printf "$${BOLD} Attempting to restore sessions\n"
|
||||
tmux new-session -d \; source-file ~/.tmux.conf \; run-shell '~/.tmux/plugins/tmux-resurrect/scripts/restore.sh'
|
||||
tmux new-session -d \; source-file ~/.tmux.conf \; run-shell "$HOME/.tmux/plugins/tmux-resurrect/scripts/restore.sh"
|
||||
printf "$${BOLD} Sessions restored: -> %s\n" "$(tmux ls)"
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 58 KiB |
@@ -1,32 +0,0 @@
|
||||
---
|
||||
display_name: Austen Bruhn
|
||||
bio: Solution Engineer at Coder, OSS enthusiast
|
||||
github: ausbru87
|
||||
avatar: ./.images/avatar.png
|
||||
linkedin: https://www.linkedin.com/in/austen-bruhn-b0a646a1/
|
||||
status: community
|
||||
---
|
||||
|
||||
# ausbru87
|
||||
|
||||
Brief description of what this namespace provides. Include information about:
|
||||
|
||||
- What types of templates/modules you offer
|
||||
- Your focus areas (e.g., specific cloud providers, technologies)
|
||||
- Any special features or configurations
|
||||
|
||||
## Templates
|
||||
|
||||
List your available templates here:
|
||||
|
||||
- **template-name**: Brief description
|
||||
|
||||
## Modules
|
||||
|
||||
List your available modules here:
|
||||
|
||||
- **module-name**: Brief description
|
||||
|
||||
## Contributing
|
||||
|
||||
If you'd like to contribute to this namespace, please [open an issue](https://github.com/coder/registry/issues) or submit a pull request.
|
||||
@@ -1,78 +0,0 @@
|
||||
---
|
||||
display_name: AWS CLI
|
||||
description: Install AWS CLI v2 in your workspace
|
||||
icon: ../../../../.icons/aws.svg
|
||||
verified: false
|
||||
tags: [helper, aws, cli]
|
||||
---
|
||||
|
||||
# AWS CLI
|
||||
|
||||
Automatically install the [AWS CLI v2](https://aws.amazon.com/cli/) in your Coder workspace with command autocomplete support for bash, zsh, and fish shells.
|
||||
|
||||
```tf
|
||||
module "aws-cli" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/ausbru87/aws-cli/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Installs AWS CLI v2 for Linux and macOS
|
||||
- Supports x86_64 and ARM64 architectures
|
||||
- Optional version pinning
|
||||
- **Auto-configures command autocomplete** for bash, zsh, and fish shells
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Installation
|
||||
|
||||
```tf
|
||||
module "aws-cli" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/ausbru87/aws-cli/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
|
||||
### Pin to Specific Version
|
||||
|
||||
```tf
|
||||
module "aws-cli" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/ausbru87/aws-cli/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
install_version = "2.15.0"
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Log Path
|
||||
|
||||
```tf
|
||||
module "aws-cli" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/ausbru87/aws-cli/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
log_path = "/var/log/aws-cli.log"
|
||||
}
|
||||
```
|
||||
|
||||
### Airgapped Environment
|
||||
|
||||
Use a custom download URL for environments without internet access to AWS:
|
||||
|
||||
```tf
|
||||
module "aws-cli" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/ausbru87/aws-cli/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
download_url = "https://internal-mirror.company.com/awscli-exe-linux-x86_64.zip"
|
||||
}
|
||||
```
|
||||
@@ -1,34 +0,0 @@
|
||||
run "required_vars" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-id"
|
||||
}
|
||||
}
|
||||
|
||||
run "with_custom_version" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-id"
|
||||
install_version = "2.15.0"
|
||||
}
|
||||
}
|
||||
|
||||
run "with_custom_log_path" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-id"
|
||||
log_path = "/var/log/aws-cli.log"
|
||||
}
|
||||
}
|
||||
|
||||
run "with_custom_download_url" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-id"
|
||||
download_url = "https://internal-mirror.company.com/awscli-exe-linux-x86_64.zip"
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
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 "install_version" {
|
||||
type = string
|
||||
description = "The version of AWS CLI to install."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "download_url" {
|
||||
type = string
|
||||
description = "Custom download URL for AWS CLI. Useful for airgapped environments. If not set, uses the official AWS download URL."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "log_path" {
|
||||
type = string
|
||||
description = "The path to the AWS CLI installation log file."
|
||||
default = "/tmp/aws-cli-install.log"
|
||||
}
|
||||
|
||||
resource "coder_script" "aws-cli" {
|
||||
agent_id = var.agent_id
|
||||
display_name = "AWS CLI"
|
||||
icon = "/icon/aws.svg"
|
||||
script = templatefile("${path.module}/run.sh", {
|
||||
LOG_PATH : var.log_path,
|
||||
VERSION : var.install_version,
|
||||
DOWNLOAD_URL : var.download_url,
|
||||
})
|
||||
run_on_start = true
|
||||
run_on_stop = false
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -e
|
||||
|
||||
LOG_PATH=${LOG_PATH}
|
||||
VERSION=${VERSION}
|
||||
DOWNLOAD_URL=${DOWNLOAD_URL}
|
||||
|
||||
BOLD='\\033[0;1m'
|
||||
RESET='\\033[0m'
|
||||
|
||||
printf "${BOLD}Installing AWS CLI...\\n${RESET}"
|
||||
|
||||
# Check if AWS CLI is already installed
|
||||
if command -v aws > /dev/null 2>&1; then
|
||||
INSTALLED_VERSION=$(aws --version 2>&1 | cut -d' ' -f1 | cut -d'/' -f2)
|
||||
if [ -n "$VERSION" ] && [ "$INSTALLED_VERSION" != "$VERSION" ]; then
|
||||
printf "❌ AWS CLI $INSTALLED_VERSION is installed, but version $VERSION was requested.\\n"
|
||||
printf "Note: AWS CLI installer does not support version-specific installation.\\n"
|
||||
exit 1
|
||||
else
|
||||
printf "AWS CLI is already installed ($INSTALLED_VERSION). Skipping installation.\\n"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Determine OS and architecture
|
||||
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
ARCH=$(uname -m)
|
||||
|
||||
case "$ARCH" in
|
||||
x86_64) ARCH="x86_64" ;;
|
||||
aarch64 | arm64) ARCH="aarch64" ;;
|
||||
*)
|
||||
printf "Unsupported architecture: $ARCH\\n" >> "${LOG_PATH}" 2>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Install AWS CLI
|
||||
if [ "$OS" = "linux" ]; then
|
||||
# Use custom download URL if provided, otherwise use default AWS URL
|
||||
if [ -z "$DOWNLOAD_URL" ]; then
|
||||
DOWNLOAD_URL="https://awscli.amazonaws.com/awscli-exe-linux-${ARCH}.zip"
|
||||
fi
|
||||
|
||||
printf "Downloading AWS CLI from $DOWNLOAD_URL...\\n"
|
||||
curl -fsSL "$DOWNLOAD_URL" -o /tmp/awscliv2.zip >> "${LOG_PATH}" 2>&1 || exit 1
|
||||
|
||||
unzip -q /tmp/awscliv2.zip -d /tmp >> "${LOG_PATH}" 2>&1 || exit 1
|
||||
sudo /tmp/aws/install >> "${LOG_PATH}" 2>&1 || exit 1
|
||||
|
||||
rm -rf /tmp/awscliv2.zip /tmp/aws
|
||||
|
||||
elif [ "$OS" = "darwin" ]; then
|
||||
# Use custom download URL if provided, otherwise use architecture-specific AWS URL
|
||||
if [ -z "$DOWNLOAD_URL" ]; then
|
||||
case "$ARCH" in
|
||||
x86_64)
|
||||
DOWNLOAD_URL="https://awscli.amazonaws.com/AWSCLIV2-x86_64.pkg"
|
||||
;;
|
||||
aarch64)
|
||||
DOWNLOAD_URL="https://awscli.amazonaws.com/AWSCLIV2-arm64.pkg"
|
||||
;;
|
||||
*)
|
||||
DOWNLOAD_URL="https://awscli.amazonaws.com/AWSCLIV2.pkg"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
printf "Downloading AWS CLI from $DOWNLOAD_URL...\\n"
|
||||
curl -fsSL "$DOWNLOAD_URL" -o /tmp/AWSCLIV2.pkg >> "${LOG_PATH}" 2>&1 || exit 1
|
||||
|
||||
sudo installer -pkg /tmp/AWSCLIV2.pkg -target / >> "${LOG_PATH}" 2>&1 || exit 1
|
||||
|
||||
rm -f /tmp/AWSCLIV2.pkg
|
||||
|
||||
else
|
||||
printf "Unsupported OS: $OS\\n" >> "${LOG_PATH}" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify installation was successful
|
||||
if command -v aws > /dev/null 2>&1; then
|
||||
printf "🥳 AWS CLI installed successfully!\\n"
|
||||
aws --version
|
||||
|
||||
# Configure autocomplete for common shells
|
||||
if command -v aws_completer > /dev/null 2>&1; then
|
||||
AWS_COMPLETER_PATH=$(which aws_completer)
|
||||
|
||||
# Bash autocomplete
|
||||
if [ -f ~/.bashrc ]; then
|
||||
if ! grep -q "aws_completer.*aws" ~/.bashrc; then
|
||||
echo "complete -C '$AWS_COMPLETER_PATH' aws" >> ~/.bashrc
|
||||
printf "✓ Configured AWS CLI autocomplete for bash\\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Zsh autocomplete
|
||||
if [ -f ~/.zshrc ] || [ -d ~/.oh-my-zsh ]; then
|
||||
if ! grep -q "aws_completer.*aws" ~/.zshrc 2> /dev/null; then
|
||||
cat >> ~/.zshrc << ZSHEOF
|
||||
|
||||
# AWS CLI autocomplete
|
||||
autoload bashcompinit && bashcompinit
|
||||
autoload -Uz compinit && compinit
|
||||
complete -C '$AWS_COMPLETER_PATH' aws
|
||||
ZSHEOF
|
||||
printf "✓ Configured AWS CLI autocomplete for zsh\\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fish autocomplete
|
||||
if [ -d ~/.config/fish ] || command -v fish > /dev/null 2>&1; then
|
||||
mkdir -p ~/.config/fish/completions
|
||||
FISH_COMPLETION=~/.config/fish/completions/aws.fish
|
||||
if [ ! -f "$FISH_COMPLETION" ]; then
|
||||
cat > "$FISH_COMPLETION" << 'FISHEOF'
|
||||
complete --command aws --no-files --arguments '(begin; set --local --export COMP_SHELL fish; set --local --export COMP_LINE (commandline); aws_completer | sed '"'"'s/ $//'"'"'; end)'
|
||||
FISHEOF
|
||||
printf "✓ Configured AWS CLI autocomplete for fish\\n"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printf "❌ AWS CLI installation failed. Check logs at ${LOG_PATH}\\n"
|
||||
exit 1
|
||||
fi
|
||||
@@ -14,7 +14,7 @@ This module installs small, robust scripts in your workspace to create and extra
|
||||
module "archive" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/archive/coder"
|
||||
version = "0.0.1"
|
||||
version = "0.0.3"
|
||||
agent_id = coder_agent.example.id
|
||||
|
||||
paths = ["./projects", "./code"]
|
||||
@@ -43,7 +43,7 @@ Basic example:
|
||||
module "archive" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/archive/coder"
|
||||
version = "0.0.1"
|
||||
version = "0.0.3"
|
||||
agent_id = coder_agent.example.id
|
||||
|
||||
# Paths to include in the archive (files or directories).
|
||||
@@ -61,7 +61,7 @@ Customize compression and output:
|
||||
module "archive" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/archive/coder"
|
||||
version = "0.0.1"
|
||||
version = "0.0.3"
|
||||
agent_id = coder_agent.example.id
|
||||
|
||||
directory = "/"
|
||||
@@ -78,7 +78,7 @@ Enable auto-archive on stop:
|
||||
module "archive" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/archive/coder"
|
||||
version = "0.0.1"
|
||||
version = "0.0.3"
|
||||
agent_id = coder_agent.example.id
|
||||
|
||||
# Creates /tmp/coder-archive.tar.gz of the users home directory (defaults).
|
||||
@@ -92,7 +92,7 @@ Extract on start:
|
||||
module "archive" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/archive/coder"
|
||||
version = "0.0.1"
|
||||
version = "0.0.3"
|
||||
agent_id = coder_agent.example.id
|
||||
|
||||
# Where to look for the archive file to extract:
|
||||
|
||||
@@ -6,8 +6,8 @@ EXTRACT_ON_START="${TF_EXTRACT_ON_START}"
|
||||
EXTRACT_WAIT_TIMEOUT="${TF_EXTRACT_WAIT_TIMEOUT}"
|
||||
|
||||
# Set script defaults from Terraform.
|
||||
DEFAULT_PATHS=(${TF_PATHS})
|
||||
DEFAULT_EXCLUDE_PATTERNS=(${TF_EXCLUDE_PATTERNS})
|
||||
IFS=' ' read -r -a DEFAULT_PATHS <<< "${TF_PATHS}"
|
||||
IFS=' ' read -r -a DEFAULT_EXCLUDE_PATTERNS <<< "${TF_EXCLUDE_PATTERNS}"
|
||||
DEFAULT_COMPRESSION="${TF_COMPRESSION}"
|
||||
DEFAULT_ARCHIVE_PATH="${TF_ARCHIVE_PATH}"
|
||||
DEFAULT_DIRECTORY="${TF_DIRECTORY}"
|
||||
@@ -62,6 +62,7 @@ echo "Installed extract script to: $EXTRACT_WRAPPER_PATH"
|
||||
|
||||
# 3) Optionally wait for and extract an archive on start.
|
||||
if [[ $EXTRACT_ON_START = true ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$LIB_PATH"
|
||||
|
||||
archive_wait_and_extract "$EXTRACT_WAIT_TIMEOUT" quiet || {
|
||||
|
||||
@@ -13,7 +13,7 @@ Run Auggie CLI in your workspace to access Augment's AI coding assistant with ad
|
||||
```tf
|
||||
module "auggie" {
|
||||
source = "registry.coder.com/coder-labs/auggie/coder"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
@@ -41,13 +41,13 @@ data "coder_parameter" "ai_prompt" {
|
||||
module "coder-login" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/coder-login/coder"
|
||||
version = "1.0.31"
|
||||
version = "0.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
|
||||
module "auggie" {
|
||||
source = "registry.coder.com/coder-labs/auggie/coder"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/project"
|
||||
|
||||
@@ -57,7 +57,7 @@ module "auggie" {
|
||||
EOF # Required for tasks
|
||||
|
||||
# Version
|
||||
auggie_version = "0.3.0"
|
||||
auggie_version = "0.2.2"
|
||||
|
||||
# Task configuration
|
||||
ai_prompt = data.coder_parameter.ai_prompt.value
|
||||
@@ -103,7 +103,7 @@ EOF
|
||||
```tf
|
||||
module "auggie" {
|
||||
source = "registry.coder.com/coder-labs/auggie/coder"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/project"
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source "$HOME"/.bashrc
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME"/.bashrc
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BOLD='\033[0;1m'
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source "$HOME"/.bashrc
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME"/.bashrc
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" > /dev/null 2>&1
|
||||
|
||||
@@ -13,7 +13,7 @@ Run Codex CLI in your workspace to access OpenAI's models through the Codex inte
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "3.1.0"
|
||||
version = "3.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
openai_api_key = var.openai_api_key
|
||||
workdir = "/home/coder/project"
|
||||
@@ -33,7 +33,7 @@ module "codex" {
|
||||
module "codex" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "3.1.0"
|
||||
version = "3.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
openai_api_key = "..."
|
||||
workdir = "/home/coder/project"
|
||||
@@ -55,13 +55,13 @@ data "coder_parameter" "ai_prompt" {
|
||||
module "coder-login" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/coder-login/coder"
|
||||
version = "1.0.31"
|
||||
version = "3.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "3.1.0"
|
||||
version = "3.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
openai_api_key = "..."
|
||||
ai_prompt = data.coder_parameter.ai_prompt.value
|
||||
@@ -108,7 +108,7 @@ For custom Codex configuration, use `base_config_toml` and/or `additional_mcp_se
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "3.1.0"
|
||||
version = "3.1.1"
|
||||
# ... other variables ...
|
||||
|
||||
# Override default configuration
|
||||
|
||||
@@ -38,7 +38,8 @@ find_session_for_directory() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
local session_id=$(grep "^$target_dir|" "$SESSION_TRACKING_FILE" | cut -d'|' -f2 | head -1)
|
||||
local session_id
|
||||
session_id=$(grep "^$target_dir|" "$SESSION_TRACKING_FILE" | cut -d'|' -f2 | head -1)
|
||||
|
||||
if [ -n "$session_id" ]; then
|
||||
echo "$session_id"
|
||||
@@ -74,9 +75,12 @@ find_recent_session_file() {
|
||||
local latest_time=0
|
||||
|
||||
while IFS= read -r session_file; do
|
||||
local file_time=$(stat -c %Y "$session_file" 2> /dev/null || stat -f %m "$session_file" 2> /dev/null || echo "0")
|
||||
local first_line=$(head -n 1 "$session_file" 2> /dev/null)
|
||||
local session_cwd=$(echo "$first_line" | grep -o '"cwd":"[^"]*"' | cut -d'"' -f4)
|
||||
local file_time
|
||||
file_time=$(stat -c %Y "$session_file" 2> /dev/null || stat -f %m "$session_file" 2> /dev/null || echo "0")
|
||||
local first_line
|
||||
first_line=$(head -n 1 "$session_file" 2> /dev/null)
|
||||
local session_cwd
|
||||
session_cwd=$(echo "$first_line" | grep -o '"cwd":"[^"]*"' | cut -d'"' -f4)
|
||||
|
||||
if [ "$session_cwd" = "$target_dir" ] && [ "$file_time" -gt "$latest_time" ]; then
|
||||
latest_file="$session_file"
|
||||
@@ -85,8 +89,10 @@ find_recent_session_file() {
|
||||
done < <(find "$sessions_dir" -type f -name "*.jsonl" 2> /dev/null)
|
||||
|
||||
if [ -n "$latest_file" ]; then
|
||||
local first_line=$(head -n 1 "$latest_file")
|
||||
local session_id=$(echo "$first_line" | grep -o '"id":"[^"]*"' | cut -d'"' -f4)
|
||||
local first_line
|
||||
first_line=$(head -n 1 "$latest_file")
|
||||
local session_id
|
||||
session_id=$(echo "$first_line" | grep -o '"id":"[^"]*"' | cut -d'"' -f4)
|
||||
if [ -n "$session_id" ]; then
|
||||
echo "$session_id"
|
||||
return 0
|
||||
@@ -102,7 +108,8 @@ wait_for_session_file() {
|
||||
local attempt=0
|
||||
|
||||
while [ $attempt -lt $max_attempts ]; do
|
||||
local session_id=$(find_recent_session_file "$target_dir" 2> /dev/null || echo "")
|
||||
local session_id
|
||||
session_id=$(find_recent_session_file "$target_dir" 2> /dev/null || echo "")
|
||||
if [ -n "$session_id" ]; then
|
||||
echo "$session_id"
|
||||
return 0
|
||||
|
||||
@@ -13,7 +13,7 @@ Run [GitHub Copilot CLI](https://docs.github.com/copilot/concepts/agents/about-c
|
||||
```tf
|
||||
module "copilot" {
|
||||
source = "registry.coder.com/coder-labs/copilot/coder"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/projects"
|
||||
}
|
||||
@@ -51,7 +51,7 @@ data "coder_parameter" "ai_prompt" {
|
||||
|
||||
module "copilot" {
|
||||
source = "registry.coder.com/coder-labs/copilot/coder"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/projects"
|
||||
|
||||
@@ -71,12 +71,12 @@ Customize tool permissions, MCP servers, and Copilot settings:
|
||||
```tf
|
||||
module "copilot" {
|
||||
source = "registry.coder.com/coder-labs/copilot/coder"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/projects"
|
||||
|
||||
# Version pinning (defaults to "latest", use specific version if desired)
|
||||
copilot_version = "0.0.334"
|
||||
copilot_version = "0.2.3"
|
||||
|
||||
# Tool permissions
|
||||
allow_tools = ["shell(git)", "shell(npm)", "write"]
|
||||
@@ -142,7 +142,7 @@ variable "github_token" {
|
||||
|
||||
module "copilot" {
|
||||
source = "registry.coder.com/coder-labs/copilot/coder"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/projects"
|
||||
github_token = var.github_token
|
||||
@@ -156,7 +156,7 @@ Run Copilot as a command-line tool without task reporting or web interface. This
|
||||
```tf
|
||||
module "copilot" {
|
||||
source = "registry.coder.com/coder-labs/copilot/coder"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder"
|
||||
report_tasks = false
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source "$HOME"/.bashrc
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME"/.bashrc
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" > /dev/null 2>&1
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME"/.bashrc
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$HOME"/.bashrc
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
command_exists() {
|
||||
|
||||
@@ -13,8 +13,8 @@ Run the Cursor Agent CLI in your workspace for interactive coding assistance and
|
||||
```tf
|
||||
module "cursor_cli" {
|
||||
source = "registry.coder.com/coder-labs/cursor-cli/coder"
|
||||
version = "0.2.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "0.2.2"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
```
|
||||
@@ -42,8 +42,8 @@ module "coder-login" {
|
||||
|
||||
module "cursor_cli" {
|
||||
source = "registry.coder.com/coder-labs/cursor-cli/coder"
|
||||
version = "0.2.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "0.2.2"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
|
||||
# Optional
|
||||
@@ -60,6 +60,7 @@ module "cursor_cli" {
|
||||
command = "npx"
|
||||
args = ["-y", "@playwright/mcp@latest", "--headless", "--isolated", "--no-sandbox"]
|
||||
}
|
||||
|
||||
desktop-commander = {
|
||||
command = "npx"
|
||||
args = ["-y", "@wonderwhy-er/desktop-commander"]
|
||||
|
||||
@@ -13,8 +13,8 @@ Run [Gemini CLI](https://github.com/google-gemini/gemini-cli) in your workspace
|
||||
```tf
|
||||
module "gemini" {
|
||||
source = "registry.coder.com/coder-labs/gemini/coder"
|
||||
version = "2.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "2.1.2"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
```
|
||||
@@ -46,8 +46,8 @@ variable "gemini_api_key" {
|
||||
|
||||
module "gemini" {
|
||||
source = "registry.coder.com/coder-labs/gemini/coder"
|
||||
version = "2.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "2.1.2"
|
||||
agent_id = coder_agent.main.id
|
||||
gemini_api_key = var.gemini_api_key
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
@@ -80,7 +80,7 @@ module "coder-login" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/coder-login/coder"
|
||||
version = "~> 1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
|
||||
data "coder_parameter" "ai_prompt" {
|
||||
@@ -94,8 +94,8 @@ data "coder_parameter" "ai_prompt" {
|
||||
module "gemini" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/gemini/coder"
|
||||
version = "2.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "2.1.2"
|
||||
agent_id = coder_agent.main.id
|
||||
gemini_api_key = var.gemini_api_key
|
||||
gemini_model = "gemini-2.5-flash"
|
||||
folder = "/home/coder/project"
|
||||
@@ -118,8 +118,8 @@ For enterprise users who prefer Google's Vertex AI platform:
|
||||
```tf
|
||||
module "gemini" {
|
||||
source = "registry.coder.com/coder-labs/gemini/coder"
|
||||
version = "2.1.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "2.1.2"
|
||||
agent_id = coder_agent.main.id
|
||||
gemini_api_key = var.gemini_api_key
|
||||
folder = "/home/coder/project"
|
||||
use_vertexai = true
|
||||
|
||||
@@ -16,7 +16,7 @@ A module that adds Nextflow to your Coder template.
|
||||
module "nextflow" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/nextflow/coder"
|
||||
version = "0.9.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "0.9.1"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
display_name: OpenCode
|
||||
icon: ../../../../.icons/opencode.svg
|
||||
description: Run OpenCode AI coding assistant for AI-powered terminal assistance
|
||||
verified: false
|
||||
tags: [agent, opencode, ai, tasks]
|
||||
---
|
||||
|
||||
# OpenCode
|
||||
|
||||
Run [OpenCode](https://opencode.ai) AI coding assistant in your workspace for intelligent code generation, analysis, and development assistance. This module integrates with [AgentAPI](https://github.com/coder/agentapi) for seamless task reporting in the Coder UI.
|
||||
|
||||
```tf
|
||||
module "opencode" {
|
||||
source = "registry.coder.com/coder-labs/opencode/coder"
|
||||
version = "0.1.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
}
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Authentication credentials** - OpenCode auth.json file is required for non-interactive authentication, you can find this file on your system: `$HOME/.local/share/opencode/auth.json`
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Usage with Tasks
|
||||
|
||||
```tf
|
||||
resource "coder_ai_task" "task" {
|
||||
app_id = module.opencode.task_app_id
|
||||
}
|
||||
|
||||
module "opencode" {
|
||||
source = "registry.coder.com/coder-labs/opencode/coder"
|
||||
version = "0.1.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
|
||||
ai_prompt = coder_ai_task.task.prompt
|
||||
|
||||
auth_json = <<-EOT
|
||||
{
|
||||
"google": {
|
||||
"type": "api",
|
||||
"key": "gem-xxx-xxxx"
|
||||
},
|
||||
"anthropic": {
|
||||
"type": "api",
|
||||
"key": "sk-ant-api03-xxx-xxxxxxx"
|
||||
}
|
||||
|
||||
}
|
||||
EOT
|
||||
|
||||
config_json = jsonencode({
|
||||
"$schema" = "https://opencode.ai/config.json"
|
||||
mcp = {
|
||||
filesystem = {
|
||||
command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/coder/projects"]
|
||||
enabled = true
|
||||
type = "local"
|
||||
environment = {
|
||||
SOME_VARIABLE_X = "value"
|
||||
}
|
||||
}
|
||||
playwright = {
|
||||
command = ["npx", "-y", "@playwright/mcp@latest", "--headless", "--isolated"]
|
||||
enabled = true
|
||||
type = "local"
|
||||
}
|
||||
}
|
||||
model = "anthropic/claude-sonnet-4-20250514"
|
||||
})
|
||||
|
||||
pre_install_script = <<-EOT
|
||||
#!/bin/bash
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
EOT
|
||||
}
|
||||
```
|
||||
|
||||
### Standalone CLI Mode
|
||||
|
||||
Run OpenCode as a command-line tool without web interface or task reporting:
|
||||
|
||||
```tf
|
||||
module "opencode" {
|
||||
source = "registry.coder.com/coder-labs/opencode/coder"
|
||||
version = "0.1.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
report_tasks = false
|
||||
cli_app = true
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you encounter any issues, check the log files in the `~/.opencode-module` directory within your workspace for detailed information.
|
||||
|
||||
## References
|
||||
|
||||
- [Opencode JSON Config](https://opencode.ai/docs/config/)
|
||||
- [OpenCode Documentation](https://opencode.ai/docs)
|
||||
- [AgentAPI Documentation](https://github.com/coder/agentapi)
|
||||
- [Coder AI Agents Guide](https://coder.com/docs/tutorials/ai-agents)
|
||||
@@ -0,0 +1,362 @@
|
||||
import {
|
||||
test,
|
||||
afterEach,
|
||||
describe,
|
||||
setDefaultTimeout,
|
||||
beforeAll,
|
||||
expect,
|
||||
} from "bun:test";
|
||||
import { execContainer, readFileContainer, runTerraformInit } from "~test";
|
||||
import {
|
||||
loadTestFile,
|
||||
writeExecutable,
|
||||
setup as setupUtil,
|
||||
execModuleScript,
|
||||
expectAgentAPIStarted,
|
||||
} from "../../../coder/modules/agentapi/test-util";
|
||||
import dedent from "dedent";
|
||||
|
||||
let cleanupFunctions: (() => Promise<void>)[] = [];
|
||||
const registerCleanup = (cleanup: () => Promise<void>) => {
|
||||
cleanupFunctions.push(cleanup);
|
||||
};
|
||||
afterEach(async () => {
|
||||
const cleanupFnsCopy = cleanupFunctions.slice().reverse();
|
||||
cleanupFunctions = [];
|
||||
for (const cleanup of cleanupFnsCopy) {
|
||||
try {
|
||||
await cleanup();
|
||||
} catch (error) {
|
||||
console.error("Error during cleanup:", error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
interface SetupProps {
|
||||
skipAgentAPIMock?: boolean;
|
||||
skipOpencodeMock?: boolean;
|
||||
moduleVariables?: Record<string, string>;
|
||||
agentapiMockScript?: string;
|
||||
}
|
||||
|
||||
const setup = async (props?: SetupProps): Promise<{ id: string }> => {
|
||||
const projectDir = "/home/coder/project";
|
||||
const { id } = await setupUtil({
|
||||
moduleDir: import.meta.dir,
|
||||
moduleVariables: {
|
||||
install_opencode: props?.skipOpencodeMock ? "true" : "false",
|
||||
install_agentapi: props?.skipAgentAPIMock ? "true" : "false",
|
||||
workdir: projectDir,
|
||||
...props?.moduleVariables,
|
||||
},
|
||||
registerCleanup,
|
||||
projectDir,
|
||||
skipAgentAPIMock: props?.skipAgentAPIMock,
|
||||
agentapiMockScript: props?.agentapiMockScript,
|
||||
});
|
||||
if (!props?.skipOpencodeMock) {
|
||||
await writeExecutable({
|
||||
containerId: id,
|
||||
filePath: "/usr/bin/opencode",
|
||||
content: await loadTestFile(import.meta.dir, "opencode-mock.sh"),
|
||||
});
|
||||
}
|
||||
return { id };
|
||||
};
|
||||
|
||||
setDefaultTimeout(60 * 1000);
|
||||
|
||||
describe("opencode", async () => {
|
||||
beforeAll(async () => {
|
||||
await runTerraformInit(import.meta.dir);
|
||||
});
|
||||
|
||||
test("happy-path", async () => {
|
||||
const { id } = await setup();
|
||||
await execModuleScript(id);
|
||||
await expectAgentAPIStarted(id);
|
||||
});
|
||||
|
||||
test("install-opencode-version", async () => {
|
||||
const version_to_install = "0.1.0";
|
||||
const { id } = await setup({
|
||||
skipOpencodeMock: true,
|
||||
moduleVariables: {
|
||||
install_opencode: "true",
|
||||
opencode_version: version_to_install,
|
||||
pre_install_script: dedent`
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Mock the opencode install for testing
|
||||
mkdir -p /home/coder/.opencode/bin
|
||||
echo '#!/bin/bash\necho "opencode mock version ${version_to_install}"' > /home/coder/.opencode/bin/opencode
|
||||
chmod +x /home/coder/.opencode/bin/opencode
|
||||
`,
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
const resp = await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
`cat /home/coder/.opencode-module/install.log`,
|
||||
]);
|
||||
expect(resp.stdout).toContain(version_to_install);
|
||||
});
|
||||
|
||||
test("check-latest-opencode-version-works", async () => {
|
||||
const { id } = await setup({
|
||||
skipOpencodeMock: true,
|
||||
skipAgentAPIMock: true,
|
||||
moduleVariables: {
|
||||
install_opencode: "true",
|
||||
pre_install_script: dedent`
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Mock the opencode install for testing
|
||||
mkdir -p /home/coder/.opencode/bin
|
||||
echo '#!/bin/bash\necho "opencode mock latest version"' > /home/coder/.opencode/bin/opencode
|
||||
chmod +x /home/coder/.opencode/bin/opencode
|
||||
`,
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
await expectAgentAPIStarted(id);
|
||||
});
|
||||
|
||||
test("opencode-auth-json", async () => {
|
||||
const authJson = JSON.stringify({
|
||||
token: "test-auth-token-123",
|
||||
user: "test-user",
|
||||
});
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
auth_json: authJson,
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const authFile = await readFileContainer(
|
||||
id,
|
||||
"/home/coder/.local/share/opencode/auth.json",
|
||||
);
|
||||
|
||||
expect(authFile).toContain("test-auth-token-123");
|
||||
expect(authFile).toContain("test-user");
|
||||
});
|
||||
|
||||
test("opencode-config-json", async () => {
|
||||
const configJson = JSON.stringify({
|
||||
$schema: "https://opencode.ai/config.json",
|
||||
mcp: {
|
||||
test: {
|
||||
command: ["test-cmd"],
|
||||
type: "local",
|
||||
},
|
||||
},
|
||||
model: "anthropic/claude-sonnet-4-20250514",
|
||||
});
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
config_json: configJson,
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const configFile = await readFileContainer(
|
||||
id,
|
||||
"/home/coder/.config/opencode/opencode.json",
|
||||
);
|
||||
expect(configFile).toContain("test-cmd");
|
||||
expect(configFile).toContain("anthropic/claude-sonnet-4-20250514");
|
||||
});
|
||||
|
||||
test("opencode-ai-prompt", async () => {
|
||||
const prompt = "This is a task prompt for OpenCode.";
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
ai_prompt: prompt,
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const resp = await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
`cat /home/coder/.opencode-module/agentapi-start.log`,
|
||||
]);
|
||||
expect(resp.stdout).toContain(prompt);
|
||||
});
|
||||
|
||||
test("opencode-continue-flag", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
continue: "true",
|
||||
ai_prompt: "test prompt",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const startLog = await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
"cat /home/coder/.opencode-module/agentapi-start.log",
|
||||
]);
|
||||
expect(startLog.stdout).toContain("--continue");
|
||||
});
|
||||
|
||||
test("opencode-continue-with-session-id", async () => {
|
||||
const sessionId = "session-123";
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
continue: "true",
|
||||
session_id: sessionId,
|
||||
ai_prompt: "test prompt",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const startLog = await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
"cat /home/coder/.opencode-module/agentapi-start.log",
|
||||
]);
|
||||
expect(startLog.stdout).toContain("--continue");
|
||||
expect(startLog.stdout).toContain(`--session ${sessionId}`);
|
||||
});
|
||||
|
||||
test("opencode-session-id", async () => {
|
||||
const sessionId = "session-123";
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
session_id: sessionId,
|
||||
ai_prompt: "test prompt",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const startLog = await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
"cat /home/coder/.opencode-module/agentapi-start.log",
|
||||
]);
|
||||
expect(startLog.stdout).toContain(`--session ${sessionId}`);
|
||||
});
|
||||
|
||||
test("opencode-report-tasks-enabled", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
report_tasks: "true",
|
||||
ai_prompt: "test prompt",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const startLog = await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
"cat /home/coder/.opencode-module/agentapi-start.log",
|
||||
]);
|
||||
expect(startLog.stdout).toContain(
|
||||
"report your progress using coder_report_task",
|
||||
);
|
||||
});
|
||||
|
||||
test("opencode-report-tasks-disabled", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
report_tasks: "false",
|
||||
ai_prompt: "test prompt",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const startLog = await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
"cat /home/coder/.opencode-module/agentapi-start.log",
|
||||
]);
|
||||
expect(startLog.stdout).not.toContain(
|
||||
"report your progress using coder_report_task",
|
||||
);
|
||||
});
|
||||
|
||||
test("cli-app-creation", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
cli_app: "true",
|
||||
cli_app_display_name: "OpenCode Terminal",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
// CLI app creation is handled by the agentapi module
|
||||
// We just verify the setup completed successfully
|
||||
await expectAgentAPIStarted(id);
|
||||
});
|
||||
|
||||
test("pre-post-install-scripts", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
pre_install_script: "#!/bin/bash\necho 'opencode-pre-install-script'",
|
||||
post_install_script: "#!/bin/bash\necho 'opencode-post-install-script'",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const preInstallLog = await readFileContainer(
|
||||
id,
|
||||
"/home/coder/.opencode-module/pre_install.log",
|
||||
);
|
||||
expect(preInstallLog).toContain("opencode-pre-install-script");
|
||||
|
||||
const postInstallLog = await readFileContainer(
|
||||
id,
|
||||
"/home/coder/.opencode-module/post_install.log",
|
||||
);
|
||||
expect(postInstallLog).toContain("opencode-post-install-script");
|
||||
});
|
||||
|
||||
test("workdir-variable", async () => {
|
||||
const workdir = "/home/coder/opencode-test-folder";
|
||||
const { id } = await setup({
|
||||
skipOpencodeMock: false,
|
||||
moduleVariables: {
|
||||
workdir,
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
|
||||
const resp = await readFileContainer(
|
||||
id,
|
||||
"/home/coder/.opencode-module/agentapi-start.log",
|
||||
);
|
||||
expect(resp).toContain(workdir);
|
||||
});
|
||||
|
||||
test("subdomain-enabled", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
subdomain: "true",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
// Subdomain configuration is handled by the agentapi module
|
||||
// We just verify the setup completed successfully
|
||||
await expectAgentAPIStarted(id);
|
||||
});
|
||||
|
||||
test("custom-display-names", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
web_app_display_name: "Custom OpenCode Web",
|
||||
cli_app_display_name: "Custom OpenCode CLI",
|
||||
cli_app: "true",
|
||||
},
|
||||
});
|
||||
await execModuleScript(id);
|
||||
// Display names are handled by the agentapi module
|
||||
// We just verify the setup completed successfully
|
||||
await expectAgentAPIStarted(id);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,203 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0"
|
||||
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
version = ">= 2.12"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "agent_id" {
|
||||
type = string
|
||||
description = "The ID of a Coder agent."
|
||||
}
|
||||
|
||||
data "coder_workspace" "me" {}
|
||||
|
||||
data "coder_workspace_owner" "me" {}
|
||||
|
||||
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 "icon" {
|
||||
type = string
|
||||
description = "The icon to use for the app."
|
||||
default = "/icon/opencode.svg"
|
||||
}
|
||||
|
||||
variable "workdir" {
|
||||
type = string
|
||||
description = "The folder to run OpenCode in."
|
||||
}
|
||||
|
||||
variable "report_tasks" {
|
||||
type = bool
|
||||
description = "Whether to enable task reporting to Coder UI via AgentAPI"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "cli_app" {
|
||||
type = bool
|
||||
description = "Whether to create a CLI app for OpenCode"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "web_app_display_name" {
|
||||
type = string
|
||||
description = "Display name for the web app"
|
||||
default = "OpenCode"
|
||||
}
|
||||
|
||||
variable "cli_app_display_name" {
|
||||
type = string
|
||||
description = "Display name for the CLI app"
|
||||
default = "OpenCode CLI"
|
||||
}
|
||||
|
||||
variable "pre_install_script" {
|
||||
type = string
|
||||
description = "Custom script to run before installing OpenCode."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "post_install_script" {
|
||||
type = string
|
||||
description = "Custom script to run after installing OpenCode."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "install_agentapi" {
|
||||
type = bool
|
||||
description = "Whether to install AgentAPI."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "agentapi_version" {
|
||||
type = string
|
||||
description = "The version of AgentAPI to install."
|
||||
default = "v0.11.2"
|
||||
}
|
||||
|
||||
variable "ai_prompt" {
|
||||
type = string
|
||||
description = "Initial task prompt for OpenCode."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "subdomain" {
|
||||
type = bool
|
||||
description = "Whether to use a subdomain for AgentAPI."
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "install_opencode" {
|
||||
type = bool
|
||||
description = "Whether to install OpenCode."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "opencode_version" {
|
||||
type = string
|
||||
description = "The version of OpenCode to install."
|
||||
default = "latest"
|
||||
}
|
||||
|
||||
variable "continue" {
|
||||
type = bool
|
||||
description = "continue the last session. Uses the --continue flag"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "session_id" {
|
||||
type = string
|
||||
description = "Session id to continue. Passed via --session"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "auth_json" {
|
||||
type = string
|
||||
description = "Your auth.json from $HOME/.local/share/opencode/auth.json, Required for non-interactive authentication"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "config_json" {
|
||||
type = string
|
||||
description = "OpenCode JSON config. https://opencode.ai/docs/config/"
|
||||
default = ""
|
||||
}
|
||||
|
||||
locals {
|
||||
workdir = trimsuffix(var.workdir, "/")
|
||||
app_slug = "opencode"
|
||||
install_script = file("${path.module}/scripts/install.sh")
|
||||
start_script = file("${path.module}/scripts/start.sh")
|
||||
module_dir_name = ".opencode-module"
|
||||
}
|
||||
|
||||
module "agentapi" {
|
||||
source = "registry.coder.com/coder/agentapi/coder"
|
||||
version = "2.0.0"
|
||||
|
||||
agent_id = var.agent_id
|
||||
web_app_slug = local.app_slug
|
||||
web_app_order = var.order
|
||||
web_app_group = var.group
|
||||
web_app_icon = var.icon
|
||||
web_app_display_name = var.web_app_display_name
|
||||
cli_app = var.cli_app
|
||||
cli_app_slug = var.cli_app ? "${local.app_slug}-cli" : null
|
||||
cli_app_display_name = var.cli_app ? var.cli_app_display_name : null
|
||||
agentapi_subdomain = var.subdomain
|
||||
folder = local.workdir
|
||||
module_dir_name = local.module_dir_name
|
||||
install_agentapi = var.install_agentapi
|
||||
agentapi_version = var.agentapi_version
|
||||
pre_install_script = var.pre_install_script
|
||||
post_install_script = var.post_install_script
|
||||
start_script = <<-EOT
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
echo -n '${base64encode(local.start_script)}' | base64 -d > /tmp/start.sh
|
||||
chmod +x /tmp/start.sh
|
||||
|
||||
ARG_WORKDIR='${local.workdir}' \
|
||||
ARG_AI_PROMPT='${base64encode(var.ai_prompt)}' \
|
||||
ARG_SESSION_ID='${var.session_id}' \
|
||||
ARG_REPORT_TASKS='${var.report_tasks}' \
|
||||
ARG_CONTINUE='${var.continue}' \
|
||||
/tmp/start.sh
|
||||
EOT
|
||||
|
||||
install_script = <<-EOT
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh
|
||||
chmod +x /tmp/install.sh
|
||||
ARG_OPENCODE_VERSION='${var.opencode_version}' \
|
||||
ARG_MCP_APP_STATUS_SLUG='${local.app_slug}' \
|
||||
ARG_INSTALL_OPENCODE='${var.install_opencode}' \
|
||||
ARG_REPORT_TASKS='${var.report_tasks}' \
|
||||
ARG_WORKDIR='${local.workdir}' \
|
||||
ARG_AUTH_JSON='${var.auth_json != null ? base64encode(replace(var.auth_json, "'", "'\\''")) : ""}' \
|
||||
ARG_OPENCODE_CONFIG='${var.config_json != null ? base64encode(replace(var.config_json, "'", "'\\''")) : ""}' \
|
||||
/tmp/install.sh
|
||||
EOT
|
||||
}
|
||||
|
||||
output "task_app_id" {
|
||||
value = module.agentapi.task_app_id
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
run "defaults_are_correct" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.install_opencode == true
|
||||
error_message = "OpenCode installation should be enabled by default"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.install_agentapi == true
|
||||
error_message = "AgentAPI installation should be enabled by default"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.agentapi_version == "v0.11.2"
|
||||
error_message = "Default AgentAPI version should be 'v0.11.2'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.opencode_version == "latest"
|
||||
error_message = "Default OpenCode version should be 'latest'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.report_tasks == true
|
||||
error_message = "Task reporting should be enabled by default"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.cli_app == false
|
||||
error_message = "CLI app should be disabled by default"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.subdomain == false
|
||||
error_message = "Subdomain should be disabled by default"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.web_app_display_name == "OpenCode"
|
||||
error_message = "Default web app display name should be 'OpenCode'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.cli_app_display_name == "OpenCode CLI"
|
||||
error_message = "Default CLI app display name should be 'OpenCode CLI'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = local.app_slug == "opencode"
|
||||
error_message = "App slug should be 'opencode'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = local.module_dir_name == ".opencode-module"
|
||||
error_message = "Module dir name should be '.opencode-module'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = local.workdir == "/home/coder/project"
|
||||
error_message = "Workdir should be trimmed of trailing slash"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.continue == false
|
||||
error_message = "Continue flag should be disabled by default"
|
||||
}
|
||||
}
|
||||
|
||||
run "workdir_trailing_slash_trimmed" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project/"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = local.workdir == "/home/coder/project"
|
||||
error_message = "Workdir should be trimmed of trailing slash"
|
||||
}
|
||||
}
|
||||
|
||||
run "opencode_version_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
opencode_version = "v1.0.0"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.opencode_version == "v1.0.0"
|
||||
error_message = "OpenCode version should be set correctly"
|
||||
}
|
||||
}
|
||||
|
||||
run "agentapi_version_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
agentapi_version = "v0.9.0"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.agentapi_version == "v0.9.0"
|
||||
error_message = "AgentAPI version should be set correctly"
|
||||
}
|
||||
}
|
||||
|
||||
run "cli_app_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
cli_app = true
|
||||
cli_app_display_name = "Custom OpenCode CLI"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.cli_app == true
|
||||
error_message = "CLI app should be enabled when specified"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.cli_app_display_name == "Custom OpenCode CLI"
|
||||
error_message = "Custom CLI app display name should be set"
|
||||
}
|
||||
}
|
||||
|
||||
run "web_app_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
web_app_display_name = "Custom OpenCode Web"
|
||||
order = 5
|
||||
group = "AI Tools"
|
||||
icon = "/custom/icon.svg"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.web_app_display_name == "Custom OpenCode Web"
|
||||
error_message = "Custom web app display name should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.order == 5
|
||||
error_message = "Custom order should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.group == "AI Tools"
|
||||
error_message = "Custom group should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.icon == "/custom/icon.svg"
|
||||
error_message = "Custom icon should be set"
|
||||
}
|
||||
}
|
||||
|
||||
run "ai_configuration_variables" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
ai_prompt = "This is a test prompt"
|
||||
session_id = "session-123"
|
||||
continue = true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.ai_prompt == "This is a test prompt"
|
||||
error_message = "AI prompt should be set correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.session_id == "session-123"
|
||||
error_message = "Session ID should be set correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.continue == true
|
||||
error_message = "Continue flag should be set correctly"
|
||||
}
|
||||
}
|
||||
|
||||
run "auth_json_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
auth_json = "{\"token\": \"test-token\", \"user\": \"test-user\"}"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.auth_json != ""
|
||||
error_message = "Auth JSON should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(jsondecode(var.auth_json))
|
||||
error_message = "Auth JSON should be valid JSON"
|
||||
}
|
||||
}
|
||||
|
||||
run "config_json_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
config_json = "{\"$schema\": \"https://opencode.ai/config.json\", \"mcp\": {\"test\": {\"command\": [\"test-cmd\"], \"type\": \"local\"}}, \"model\": \"anthropic/claude-sonnet-4-20250514\"}"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.config_json != ""
|
||||
error_message = "OpenCode JSON configuration should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(jsondecode(var.config_json))
|
||||
error_message = "OpenCode JSON configuration should be valid JSON"
|
||||
}
|
||||
}
|
||||
|
||||
run "task_reporting_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
report_tasks = false
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.report_tasks == false
|
||||
error_message = "Task reporting should be disabled when specified"
|
||||
}
|
||||
}
|
||||
|
||||
run "subdomain_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
subdomain = true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.subdomain == true
|
||||
error_message = "Subdomain should be enabled when specified"
|
||||
}
|
||||
}
|
||||
|
||||
run "install_flags_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
install_opencode = false
|
||||
install_agentapi = false
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.install_opencode == false
|
||||
error_message = "OpenCode installation should be disabled when specified"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.install_agentapi == false
|
||||
error_message = "AgentAPI installation should be disabled when specified"
|
||||
}
|
||||
}
|
||||
|
||||
run "custom_scripts_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
pre_install_script = "#!/bin/bash\necho 'pre-install'"
|
||||
post_install_script = "#!/bin/bash\necho 'post-install'"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.pre_install_script != null
|
||||
error_message = "Pre-install script should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.post_install_script != null
|
||||
error_message = "Post-install script should be set"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("pre-install", var.pre_install_script))
|
||||
error_message = "Pre-install script should contain expected content"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = can(regex("post-install", var.post_install_script))
|
||||
error_message = "Post-install script should contain expected content"
|
||||
}
|
||||
}
|
||||
|
||||
run "empty_variables_handled_correctly" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
ai_prompt = ""
|
||||
session_id = ""
|
||||
auth_json = ""
|
||||
config_json = ""
|
||||
continue = false
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.ai_prompt == ""
|
||||
error_message = "Empty AI prompt should be handled correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.session_id == ""
|
||||
error_message = "Empty session ID should be handled correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.auth_json == ""
|
||||
error_message = "Empty auth JSON should be handled correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.config_json == ""
|
||||
error_message = "Empty config JSON should be handled correctly"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.continue == false
|
||||
error_message = "Continue flag default should be handled correctly"
|
||||
}
|
||||
}
|
||||
|
||||
run "continue_flag_configuration" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder/project"
|
||||
continue = true
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.continue == true
|
||||
error_message = "Continue flag should be enabled when specified"
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
ARG_WORKDIR=${ARG_WORKDIR:-"$HOME"}
|
||||
ARG_REPORT_TASKS=${ARG_REPORT_TASKS:-true}
|
||||
ARG_MCP_APP_STATUS_SLUG=${ARG_MCP_APP_STATUS_SLUG:-}
|
||||
ARG_OPENCODE_VERSION=${ARG_OPENCODE_VERSION:-latest}
|
||||
ARG_INSTALL_OPENCODE=${ARG_INSTALL_OPENCODE:-true}
|
||||
ARG_AUTH_JSON=$(echo -n "$ARG_AUTH_JSON" | base64 -d 2> /dev/null || echo "")
|
||||
ARG_OPENCODE_CONFIG=$(echo -n "$ARG_OPENCODE_CONFIG" | base64 -d 2> /dev/null || echo "")
|
||||
|
||||
# Print all received environment variables
|
||||
printf "=== INSTALL CONFIG ===\n"
|
||||
printf "ARG_WORKDIR: %s\n" "$ARG_WORKDIR"
|
||||
printf "ARG_REPORT_TASKS: %s\n" "$ARG_REPORT_TASKS"
|
||||
printf "ARG_MCP_APP_STATUS_SLUG: %s\n" "$ARG_MCP_APP_STATUS_SLUG"
|
||||
printf "ARG_OPENCODE_VERSION: %s\n" "$ARG_OPENCODE_VERSION"
|
||||
printf "ARG_INSTALL_OPENCODE: %s\n" "$ARG_INSTALL_OPENCODE"
|
||||
if [ -n "$ARG_AUTH_JSON" ]; then
|
||||
printf "ARG_AUTH_JSON: [AUTH DATA RECEIVED]\n"
|
||||
else
|
||||
printf "ARG_AUTH_JSON: [NOT PROVIDED]\n"
|
||||
fi
|
||||
if [ -n "$ARG_OPENCODE_CONFIG" ]; then
|
||||
printf "ARG_OPENCODE_CONFIG: [RECEIVED]\n"
|
||||
else
|
||||
printf "ARG_OPENCODE_CONFIG: [NOT PROVIDED]\n"
|
||||
fi
|
||||
printf "==================================\n"
|
||||
|
||||
install_opencode() {
|
||||
if [ "$ARG_INSTALL_OPENCODE" = "true" ]; then
|
||||
if ! command_exists opencode; then
|
||||
echo "Installing OpenCode (version: ${ARG_OPENCODE_VERSION})..."
|
||||
if [ "$ARG_OPENCODE_VERSION" = "latest" ]; then
|
||||
curl -fsSL https://opencode.ai/install | bash
|
||||
else
|
||||
VERSION=$ARG_OPENCODE_VERSION curl -fsSL https://opencode.ai/install | bash
|
||||
fi
|
||||
export PATH=/home/coder/.opencode/bin:$PATH
|
||||
printf "Opencode location: %s\n" "$(which opencode)"
|
||||
if ! command_exists opencode; then
|
||||
echo "ERROR: Failed to install OpenCode"
|
||||
exit 1
|
||||
fi
|
||||
echo "OpenCode installed successfully"
|
||||
else
|
||||
echo "OpenCode already installed"
|
||||
fi
|
||||
else
|
||||
echo "OpenCode installation skipped (ARG_INSTALL_OPENCODE=false)"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_opencode_config() {
|
||||
local opencode_config_file="$HOME/.config/opencode/opencode.json"
|
||||
local auth_json_file="$HOME/.local/share/opencode/auth.json"
|
||||
|
||||
mkdir -p "$(dirname "$auth_json_file")"
|
||||
mkdir -p "$(dirname "$opencode_config_file")"
|
||||
|
||||
setup_opencode_auth "$auth_json_file"
|
||||
|
||||
if [ -n "$ARG_OPENCODE_CONFIG" ]; then
|
||||
echo "Writing to the config file"
|
||||
echo "$ARG_OPENCODE_CONFIG" > "$opencode_config_file"
|
||||
fi
|
||||
|
||||
if [ "$ARG_REPORT_TASKS" = "true" ]; then
|
||||
setup_coder_mcp_server "$opencode_config_file"
|
||||
fi
|
||||
|
||||
echo "MCP configuration completed: $opencode_config_file"
|
||||
}
|
||||
|
||||
setup_opencode_auth() {
|
||||
local auth_json_file="$1"
|
||||
|
||||
if [ -n "$ARG_AUTH_JSON" ]; then
|
||||
echo "$ARG_AUTH_JSON" > "$auth_json_file"
|
||||
printf "added auth json to %s" "$auth_json_file"
|
||||
else
|
||||
printf "auth json not provided"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_coder_mcp_server() {
|
||||
local opencode_config_file="$1"
|
||||
|
||||
# Set environment variables based on task reporting setting
|
||||
echo "Configuring OpenCode task reporting"
|
||||
export CODER_MCP_APP_STATUS_SLUG="$ARG_MCP_APP_STATUS_SLUG"
|
||||
export CODER_MCP_AI_AGENTAPI_URL="http://localhost:3284"
|
||||
echo "Coder integration configured for task reporting"
|
||||
|
||||
# Add coder MCP server configuration to the JSON file
|
||||
echo "Adding Coder MCP server configuration"
|
||||
|
||||
# Create the coder server configuration JSON
|
||||
coder_config=$(
|
||||
cat << EOF
|
||||
{
|
||||
"type": "local",
|
||||
"command": ["coder", "exp", "mcp", "server"],
|
||||
"enabled": true,
|
||||
"environment": {
|
||||
"CODER_MCP_APP_STATUS_SLUG": "${CODER_MCP_APP_STATUS_SLUG:-}",
|
||||
"CODER_MCP_AI_AGENTAPI_URL": "${CODER_MCP_AI_AGENTAPI_URL:-}",
|
||||
"CODER_AGENT_URL": "${CODER_AGENT_URL:-}",
|
||||
"CODER_AGENT_TOKEN": "${CODER_AGENT_TOKEN:-}",
|
||||
"CODER_MCP_ALLOWED_TOOLS": "coder_report_task"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
temp_file=$(mktemp)
|
||||
jq --argjson coder_config "$coder_config" '.mcp.coder = $coder_config' "$opencode_config_file" > "$temp_file"
|
||||
mv "$temp_file" "$opencode_config_file"
|
||||
echo "Coder MCP server configuration added"
|
||||
|
||||
}
|
||||
|
||||
install_opencode
|
||||
setup_opencode_config
|
||||
|
||||
echo "OpenCode module setup completed."
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export PATH=/home/coder/.opencode/bin:$PATH
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
ARG_WORKDIR=${ARG_WORKDIR:-"$HOME"}
|
||||
ARG_AI_PROMPT=$(echo -n "${ARG_AI_PROMPT:-}" | base64 -d 2> /dev/null || echo "")
|
||||
ARG_REPORT_TASKS=${ARG_REPORT_TASKS:-true}
|
||||
ARG_SESSION_ID=${ARG_SESSION_ID:-}
|
||||
ARG_CONTINUE=${ARG_CONTINUE:-false}
|
||||
|
||||
# Print all received environment variables
|
||||
printf "=== START CONFIG ===\n"
|
||||
printf "ARG_WORKDIR: %s\n" "$ARG_WORKDIR"
|
||||
printf "ARG_REPORT_TASKS: %s\n" "$ARG_REPORT_TASKS"
|
||||
printf "ARG_CONTINUE: %s\n" "$ARG_CONTINUE"
|
||||
printf "ARG_SESSION_ID: %s\n" "$ARG_SESSION_ID"
|
||||
if [ -n "$ARG_AI_PROMPT" ]; then
|
||||
printf "ARG_AI_PROMPT: [AI PROMPT RECEIVED]\n"
|
||||
else
|
||||
printf "ARG_AI_PROMPT: [NOT PROVIDED]\n"
|
||||
fi
|
||||
printf "==================================\n"
|
||||
|
||||
OPENCODE_ARGS=()
|
||||
AGENTAPI_ARGS=()
|
||||
|
||||
validate_opencode_installation() {
|
||||
if ! command_exists opencode; then
|
||||
printf "ERROR: OpenCode not installed. Set install_opencode to true\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
build_opencode_args() {
|
||||
|
||||
if [ -n "$ARG_SESSION_ID" ]; then
|
||||
OPENCODE_ARGS+=(--session "$ARG_SESSION_ID")
|
||||
fi
|
||||
|
||||
if [ "$ARG_CONTINUE" = "true" ]; then
|
||||
OPENCODE_ARGS+=(--continue)
|
||||
fi
|
||||
|
||||
if [ -n "$ARG_AI_PROMPT" ]; then
|
||||
if [ "$ARG_REPORT_TASKS" = "true" ]; then
|
||||
PROMPT="Every step of the way, report your progress using coder_report_task tool with proper summary and statuses. Your task at hand: $ARG_AI_PROMPT"
|
||||
else
|
||||
PROMPT="$ARG_AI_PROMPT"
|
||||
fi
|
||||
AGENTAPI_ARGS+=(-I "$PROMPT")
|
||||
fi
|
||||
}
|
||||
|
||||
start_agentapi() {
|
||||
printf "Starting in directory: %s\n" "$ARG_WORKDIR"
|
||||
cd "$ARG_WORKDIR"
|
||||
|
||||
build_opencode_args
|
||||
|
||||
printf "Running OpenCode with args: %s\n" "${OPENCODE_ARGS[*]}"
|
||||
echo agentapi server "${AGENTAPI_ARGS[@]}" --type opencode --term-width 67 --term-height 1190 -- opencode "${OPENCODE_ARGS[@]}"
|
||||
agentapi server "${AGENTAPI_ARGS[@]}" --type opencode --term-width 67 --term-height 1190 -- opencode "${OPENCODE_ARGS[@]}"
|
||||
}
|
||||
|
||||
validate_opencode_installation
|
||||
start_agentapi
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Mock OpenCode CLI for testing purposes
|
||||
# This script simulates the OpenCode command-line interface
|
||||
|
||||
echo "OpenCode Mock CLI - Test Version"
|
||||
echo "Args received: $*"
|
||||
|
||||
# Simulate opencode behavior based on arguments
|
||||
case "$1" in
|
||||
--version | -v)
|
||||
echo "opencode mock version 0.1.0-test"
|
||||
;;
|
||||
--help | -h)
|
||||
echo "OpenCode Mock Help"
|
||||
echo "Usage: opencode [options] [command]"
|
||||
echo "This is a mock version for testing"
|
||||
;;
|
||||
*)
|
||||
echo "Running OpenCode mock with arguments: $*"
|
||||
echo "Mock execution completed successfully"
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -13,11 +13,11 @@ Run [Amp CLI](https://ampcode.com/) in your workspace to access Sourcegraph's AI
|
||||
```tf
|
||||
module "amp-cli" {
|
||||
source = "registry.coder.com/coder-labs/sourcegraph-amp/coder"
|
||||
version = "2.0.1"
|
||||
version = "2.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
sourcegraph_amp_api_key = var.sourcegraph_amp_api_key
|
||||
install_sourcegraph_amp = true
|
||||
agentapi_version = "latest"
|
||||
agentapi_version = "2.0.2"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -48,7 +48,7 @@ variable "amp_api_key" {
|
||||
module "amp-cli" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder-labs/sourcegraph-amp/coder"
|
||||
amp_version = "2.0.1"
|
||||
amp_version = "2.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
amp_api_key = var.amp_api_key # recommended for tasks usage
|
||||
workdir = "/home/coder/project"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source "$HOME"/.bashrc
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME"/.bashrc
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ANSI colors
|
||||
BOLD='\033[1m'
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Load user environment
|
||||
# shellcheck source=/dev/null
|
||||
source "$HOME/.bashrc"
|
||||
# shellcheck source=/dev/null
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
source "$HOME/.bashrc"
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.nvm/nvm.sh" ]; then
|
||||
source "$HOME/.nvm/nvm.sh"
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
export PATH="$HOME/.local/bin:$HOME/.amp/bin:$HOME/.npm-global/bin:$PATH"
|
||||
|
||||
function ensure_command() {
|
||||
|
||||
@@ -19,8 +19,8 @@ variable "api_key" {
|
||||
|
||||
module "aider" {
|
||||
source = "registry.coder.com/coder/aider/coder"
|
||||
version = "2.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "2.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
api_key = var.api_key
|
||||
ai_provider = "google"
|
||||
model = "gemini"
|
||||
@@ -50,8 +50,8 @@ variable "gemini_api_key" {
|
||||
|
||||
module "aider" {
|
||||
source = "registry.coder.com/coder/aider/coder"
|
||||
version = "2.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "2.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
api_key = var.gemini_api_key
|
||||
install_aider = true
|
||||
workdir = "/home/coder"
|
||||
@@ -75,8 +75,8 @@ variable "custom_api_key" {
|
||||
module "aider" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/aider/coder"
|
||||
version = "2.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "2.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
ai_provider = "custom"
|
||||
custom_env_var_name = "MY_CUSTOM_API_KEY"
|
||||
|
||||
@@ -19,7 +19,7 @@ module "dcv" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/amazon-dcv-windows/coder"
|
||||
version = "1.1.1"
|
||||
agent_id = resource.coder_agent.main.id
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
|
||||
resource "coder_metadata" "dcv" {
|
||||
|
||||
@@ -13,8 +13,8 @@ Run [Amazon Q](https://aws.amazon.com/q/) in your workspace to access Amazon's A
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
|
||||
# Required: Authentication tarball (see below for generation)
|
||||
@@ -102,8 +102,8 @@ data "coder_parameter" "ai_prompt" {
|
||||
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
ai_prompt = data.coder_parameter.ai_prompt.value
|
||||
@@ -228,8 +228,8 @@ If no custom `agent_config` is provided, the default agent name "agent" is used.
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
}
|
||||
@@ -258,8 +258,8 @@ This example will:
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
ai_prompt = "Help me set up a Python FastAPI project with proper testing structure"
|
||||
@@ -279,8 +279,8 @@ module "amazon-q" {
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
|
||||
@@ -305,8 +305,8 @@ module "amazon-q" {
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
amazon_q_version = "1.14.0" # Specific version
|
||||
@@ -319,8 +319,8 @@ module "amazon-q" {
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
|
||||
@@ -331,6 +331,7 @@ module "amazon-q" {
|
||||
"prompt": "You are a specialized DevOps assistant...",
|
||||
"tools": ["fs_read", "fs_write", "execute_bash", "use_aws"]
|
||||
}
|
||||
|
||||
EOT
|
||||
}
|
||||
```
|
||||
@@ -340,8 +341,8 @@ module "amazon-q" {
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
|
||||
@@ -358,8 +359,8 @@ For environments without direct internet access, you can host Amazon Q installat
|
||||
```tf
|
||||
module "amazon-q" {
|
||||
source = "registry.coder.com/coder/amazon-q/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder"
|
||||
auth_tarball = var.amazon_q_auth_tarball
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.2.0"
|
||||
version = "4.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
claude_api_key = "xxxx-xxxxx-xxxx"
|
||||
@@ -46,12 +46,12 @@ This example shows how to configure the Claude Code module to run the agent behi
|
||||
module "claude-code" {
|
||||
source = "dev.registry.coder.com/coder/claude-code/coder"
|
||||
enable_boundary = true
|
||||
boundary_version = "main"
|
||||
boundary_version = "4.2.2"
|
||||
boundary_log_dir = "/tmp/boundary_logs"
|
||||
boundary_log_level = "WARN"
|
||||
boundary_additional_allowed_urls = ["GET *google.com"]
|
||||
boundary_proxy_port = "8087"
|
||||
version = "3.4.3"
|
||||
version = "4.2.2"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -70,7 +70,7 @@ data "coder_parameter" "ai_prompt" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.2.0"
|
||||
version = "4.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
|
||||
@@ -78,8 +78,8 @@ module "claude-code" {
|
||||
# OR
|
||||
claude_code_oauth_token = "xxxxx-xxxx-xxxx"
|
||||
|
||||
claude_code_version = "1.0.82" # Pin to a specific version
|
||||
agentapi_version = "v0.10.0"
|
||||
claude_code_version = "4.2.2" # Pin to a specific version
|
||||
agentapi_version = "4.2.2"
|
||||
|
||||
ai_prompt = data.coder_parameter.ai_prompt.value
|
||||
model = "sonnet"
|
||||
@@ -106,11 +106,11 @@ Run and configure Claude Code as a standalone CLI in your workspace.
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.2.0"
|
||||
version = "4.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder"
|
||||
install_claude_code = true
|
||||
claude_code_version = "latest"
|
||||
claude_code_version = "4.2.2"
|
||||
report_tasks = false
|
||||
cli_app = true
|
||||
}
|
||||
@@ -129,7 +129,7 @@ variable "claude_code_oauth_token" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.2.0"
|
||||
version = "4.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
claude_code_oauth_token = var.claude_code_oauth_token
|
||||
@@ -202,7 +202,7 @@ resource "coder_env" "bedrock_api_key" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.2.0"
|
||||
version = "4.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
|
||||
@@ -259,7 +259,7 @@ resource "coder_env" "google_application_credentials" {
|
||||
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.2.0"
|
||||
version = "4.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
model = "claude-sonnet-4@20250514"
|
||||
|
||||
@@ -68,13 +68,16 @@ function setup_claude_configurations() {
|
||||
mkdir -p "$module_path"
|
||||
|
||||
if [ "$ARG_MCP" != "" ]; then
|
||||
while IFS= read -r server_name && IFS= read -r server_json; do
|
||||
echo "------------------------"
|
||||
echo "Executing: claude mcp add \"$server_name\" '$server_json'"
|
||||
claude mcp add "$server_name" "$server_json"
|
||||
echo "------------------------"
|
||||
echo ""
|
||||
done < <(echo "$ARG_MCP" | jq -r '.mcpServers | to_entries[] | .key, (.value | @json)')
|
||||
(
|
||||
cd "$ARG_WORKDIR"
|
||||
while IFS= read -r server_name && IFS= read -r server_json; do
|
||||
echo "------------------------"
|
||||
echo "Executing: claude mcp add-json \"$server_name\" '$server_json' (in $ARG_WORKDIR)"
|
||||
claude mcp add-json "$server_name" "$server_json"
|
||||
echo "------------------------"
|
||||
echo ""
|
||||
done < <(echo "$ARG_MCP" | jq -r '.mcpServers | to_entries[] | .key, (.value | @json)')
|
||||
)
|
||||
fi
|
||||
|
||||
if [ -n "$ARG_ALLOWED_TOOLS" ]; then
|
||||
|
||||
@@ -100,12 +100,17 @@ function validate_claude_installation() {
|
||||
TASK_SESSION_ID="cd32e253-ca16-4fd3-9825-d837e74ae3c2"
|
||||
|
||||
task_session_exists() {
|
||||
local workdir_normalized=$(echo "$ARG_WORKDIR" | tr '/' '-')
|
||||
local workdir_normalized
|
||||
workdir_normalized=$(echo "$ARG_WORKDIR" | tr '/' '-')
|
||||
local project_dir="$HOME/.claude/projects/${workdir_normalized}"
|
||||
|
||||
printf "PROJECT_DIR: %s, workdir_normalized: %s\n" "$project_dir" "$workdir_normalized"
|
||||
|
||||
if [ -d "$project_dir" ] && find "$project_dir" -type f -name "*${TASK_SESSION_ID}*" 2> /dev/null | grep -q .; then
|
||||
printf "TASK_SESSION_ID: %s file found\n" "$TASK_SESSION_ID"
|
||||
return 0
|
||||
else
|
||||
printf "TASK_SESSION_ID: %s file not found\n" "$TASK_SESSION_ID"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -149,7 +154,11 @@ function start_agentapi() {
|
||||
else
|
||||
echo "No existing session found"
|
||||
if [ "$ARG_REPORT_TASKS" = "true" ]; then
|
||||
ARGS+=(--session-id "$TASK_SESSION_ID")
|
||||
if task_session_exists; then
|
||||
ARGS+=(--resume "$TASK_SESSION_ID")
|
||||
else
|
||||
ARGS+=(--session-id "$TASK_SESSION_ID")
|
||||
fi
|
||||
fi
|
||||
if [ -n "$ARG_AI_PROMPT" ]; then
|
||||
if [ "$ARG_REPORT_TASKS" = "true" ]; then
|
||||
@@ -171,7 +180,11 @@ function start_agentapi() {
|
||||
else
|
||||
echo "Continue disabled, starting fresh session"
|
||||
if [ "$ARG_REPORT_TASKS" = "true" ]; then
|
||||
ARGS+=(--session-id "$TASK_SESSION_ID")
|
||||
if task_session_exists; then
|
||||
ARGS+=(--resume "$TASK_SESSION_ID")
|
||||
else
|
||||
ARGS+=(--session-id "$TASK_SESSION_ID")
|
||||
fi
|
||||
fi
|
||||
if [ -n "$ARG_AI_PROMPT" ]; then
|
||||
if [ "$ARG_REPORT_TASKS" = "true" ]; then
|
||||
@@ -214,15 +227,15 @@ function start_agentapi() {
|
||||
fi
|
||||
|
||||
# Set HTTP Proxy port used by Boundary
|
||||
BOUNDARY_ARGS+=(--proxy-port $ARG_BOUNDARY_PROXY_PORT)
|
||||
BOUNDARY_ARGS+=(--proxy-port "$ARG_BOUNDARY_PROXY_PORT")
|
||||
|
||||
# Set log level for boundary
|
||||
BOUNDARY_ARGS+=(--log-level $ARG_BOUNDARY_LOG_LEVEL)
|
||||
BOUNDARY_ARGS+=(--log-level "$ARG_BOUNDARY_LOG_LEVEL")
|
||||
|
||||
if [ "${ARG_ENABLE_BOUNDARY_PPROF:-false}" = "true" ]; then
|
||||
# Enable boundary pprof server on specified port
|
||||
BOUNDARY_ARGS+=(--pprof)
|
||||
BOUNDARY_ARGS+=(--pprof-port ${ARG_BOUNDARY_PPROF_PORT})
|
||||
BOUNDARY_ARGS+=(--pprof-port "$ARG_BOUNDARY_PPROF_PORT")
|
||||
fi
|
||||
|
||||
agentapi server --type claude --term-width 67 --term-height 1190 -- \
|
||||
|
||||
@@ -14,7 +14,7 @@ Automatically install [code-server](https://github.com/coder/code-server) in a w
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -29,9 +29,9 @@ module "code-server" {
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
install_version = "4.8.3"
|
||||
install_version = "1.4.1"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,7 +43,7 @@ Install the Dracula theme from [OpenVSX](https://open-vsx.org/):
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = [
|
||||
"dracula-theme.theme-dracula"
|
||||
@@ -61,7 +61,7 @@ Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarte
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = ["dracula-theme.theme-dracula"]
|
||||
settings = {
|
||||
@@ -78,7 +78,7 @@ Just run code-server in the background, don't fetch it from GitHub:
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
|
||||
}
|
||||
@@ -92,7 +92,7 @@ You can pass additional command-line arguments to code-server using the `additio
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
additional_args = "--disable-workspace-trust"
|
||||
}
|
||||
@@ -108,7 +108,7 @@ Run an existing copy of code-server if found, otherwise download from GitHub:
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
use_cached = true
|
||||
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
|
||||
@@ -121,7 +121,7 @@ Just run code-server in the background, don't fetch it from GitHub:
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
agent_id = coder_agent.example.id
|
||||
offline = true
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ function extension_installed() {
|
||||
if [ "${USE_CACHED_EXTENSIONS}" != true ]; then
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2066
|
||||
for _extension in "$${EXTENSIONS_ARRAY[@]}"; do
|
||||
if [ "$_extension" == "$1" ]; then
|
||||
echo "Extension $1 was already installed."
|
||||
@@ -99,6 +100,7 @@ function extension_installed() {
|
||||
|
||||
# Install each extension...
|
||||
IFS=',' read -r -a EXTENSIONLIST <<< "$${EXTENSIONS}"
|
||||
# shellcheck disable=SC2066
|
||||
for extension in "$${EXTENSIONLIST[@]}"; do
|
||||
if [ -z "$extension" ]; then
|
||||
continue
|
||||
|
||||
@@ -14,8 +14,8 @@ Automatically logs the user into Coder when creating their workspace.
|
||||
module "coder-login" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/coder-login/coder"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.1.1"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ Uses the [Coder Remote VS Code Extension](https://github.com/coder/vscode-coder)
|
||||
module "cursor" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/cursor/coder"
|
||||
version = "1.3.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -29,8 +29,8 @@ module "cursor" {
|
||||
module "cursor" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/cursor/coder"
|
||||
version = "1.3.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
```
|
||||
@@ -45,8 +45,8 @@ The following example configures Cursor to use the GitHub MCP server with authen
|
||||
module "cursor" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/cursor/coder"
|
||||
version = "1.3.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
mcp = jsonencode({
|
||||
mcpServers = {
|
||||
@@ -57,6 +57,8 @@ module "cursor" {
|
||||
},
|
||||
"type" : "http"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ describe("cursor", async () => {
|
||||
);
|
||||
|
||||
const coder_app = state.resources.find(
|
||||
(res) => res.type === "coder_app" && res.name === "cursor",
|
||||
(res) =>
|
||||
res.type === "coder_app" &&
|
||||
res.module === "module.vscode-desktop-core" &&
|
||||
res.name === "vscode-desktop",
|
||||
);
|
||||
|
||||
expect(coder_app).not.toBeNull();
|
||||
@@ -76,21 +79,6 @@ describe("cursor", async () => {
|
||||
);
|
||||
});
|
||||
|
||||
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 === "cursor",
|
||||
);
|
||||
|
||||
expect(coder_app).not.toBeNull();
|
||||
expect(coder_app?.instances.length).toBe(1);
|
||||
expect(coder_app?.instances[0].attributes.order).toBe(22);
|
||||
});
|
||||
|
||||
it("writes ~/.cursor/mcp.json when mcp provided", async () => {
|
||||
const id = await runContainer("alpine");
|
||||
try {
|
||||
|
||||
@@ -64,26 +64,21 @@ locals {
|
||||
mcp_b64 = var.mcp != "" ? base64encode(var.mcp) : ""
|
||||
}
|
||||
|
||||
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",
|
||||
])
|
||||
module "vscode-desktop-core" {
|
||||
source = "registry.coder.com/coder/vscode-desktop-core/coder"
|
||||
version = "1.0.0"
|
||||
|
||||
agent_id = var.agent_id
|
||||
|
||||
coder_app_icon = "/icon/cursor.svg"
|
||||
coder_app_slug = var.slug
|
||||
coder_app_display_name = var.display_name
|
||||
coder_app_order = var.order
|
||||
coder_app_group = var.group
|
||||
|
||||
folder = var.folder
|
||||
open_recent = var.open_recent
|
||||
protocol = "cursor"
|
||||
}
|
||||
|
||||
resource "coder_script" "cursor_mcp" {
|
||||
@@ -103,6 +98,6 @@ resource "coder_script" "cursor_mcp" {
|
||||
}
|
||||
|
||||
output "cursor_url" {
|
||||
value = coder_app.cursor.url
|
||||
value = module.vscode-desktop-core.ide_uri
|
||||
description = "Cursor IDE Desktop URL."
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ The devcontainers-cli module provides an easy way to install [`@devcontainers/cl
|
||||
```tf
|
||||
module "devcontainers-cli" {
|
||||
source = "registry.coder.com/coder/devcontainers-cli/coder"
|
||||
version = "1.0.32"
|
||||
version = "1.0.34"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# might contain a `package.json` with `packageManager` set to something
|
||||
# other than the detected package manager. When this happens, it can
|
||||
# cause the installation to fail.
|
||||
cd "$CODER_SCRIPT_DATA_DIR"
|
||||
cd "$CODER_SCRIPT_DATA_DIR" || exit
|
||||
|
||||
# If @devcontainers/cli is already installed, we can skip
|
||||
if command -v devcontainer > /dev/null 2>&1; then
|
||||
|
||||
@@ -18,7 +18,7 @@ Under the hood, this module uses the [coder dotfiles](https://coder.com/docs/v2/
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -31,7 +31,7 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -42,7 +42,7 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
user = "root"
|
||||
}
|
||||
@@ -54,14 +54,14 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
|
||||
module "dotfiles-root" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
user = "root"
|
||||
dotfiles_uri = module.dotfiles.dotfiles_uri
|
||||
@@ -76,7 +76,7 @@ You can set a default dotfiles repository for all users by setting the `default_
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.example.id
|
||||
default_dotfiles_uri = "https://github.com/coder/dotfiles"
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ set -euo pipefail
|
||||
DOTFILES_URI="${DOTFILES_URI}"
|
||||
DOTFILES_USER="${DOTFILES_USER}"
|
||||
|
||||
# shellcheck disable=SC2157
|
||||
if [ -n "$${DOTFILES_URI// }" ]; then
|
||||
if [ -z "$DOTFILES_USER" ]; then
|
||||
DOTFILES_USER="$USER"
|
||||
|
||||
@@ -14,8 +14,8 @@ A file browser for your workspace.
|
||||
module "filebrowser" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/filebrowser/coder"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.1.3"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -29,8 +29,8 @@ module "filebrowser" {
|
||||
module "filebrowser" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/filebrowser/coder"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.1.3"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
```
|
||||
@@ -41,8 +41,8 @@ module "filebrowser" {
|
||||
module "filebrowser" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/filebrowser/coder"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.1.3"
|
||||
agent_id = coder_agent.main.id
|
||||
database_path = ".config/filebrowser.db"
|
||||
}
|
||||
```
|
||||
@@ -53,8 +53,8 @@ module "filebrowser" {
|
||||
module "filebrowser" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/filebrowser/coder"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.1.3"
|
||||
agent_id = coder_agent.main.id
|
||||
agent_name = "main"
|
||||
subdomain = false
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ This module allows you to automatically clone a repository by URL and skip if it
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
}
|
||||
@@ -28,7 +28,7 @@ module "git-clone" {
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
base_dir = "~/projects/coder"
|
||||
@@ -43,7 +43,7 @@ To use with [Git Authentication](https://coder.com/docs/v2/latest/admin/git-prov
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
}
|
||||
@@ -69,7 +69,7 @@ data "coder_parameter" "git_repo" {
|
||||
module "git_clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = data.coder_parameter.git_repo.value
|
||||
}
|
||||
@@ -78,7 +78,7 @@ module "git_clone" {
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.0.18"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
order = 1
|
||||
folder = "/home/${local.username}/${module.git_clone[count.index].folder_name}"
|
||||
@@ -103,7 +103,7 @@ Configuring `git-clone` for a self-hosted GitHub Enterprise Server running at `g
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.example.com/coder/coder/tree/feat/example"
|
||||
git_providers = {
|
||||
@@ -122,7 +122,7 @@ To GitLab clone with a specific branch like `feat/example`
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://gitlab.com/coder/coder/-/tree/feat/example"
|
||||
}
|
||||
@@ -134,7 +134,7 @@ Configuring `git-clone` for a self-hosted GitLab running at `gitlab.example.com`
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://gitlab.example.com/coder/coder/-/tree/feat/example"
|
||||
git_providers = {
|
||||
@@ -155,7 +155,7 @@ For example, to clone the `feat/example` branch:
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
branch_name = "feat/example"
|
||||
@@ -173,7 +173,7 @@ For example, this will clone into the `~/projects/coder/coder-dev` folder:
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
folder_name = "coder-dev"
|
||||
@@ -192,7 +192,7 @@ If not defined, the default, `0`, performs a full clone.
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/modules/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
depth = 1
|
||||
@@ -208,7 +208,7 @@ This is useful for running initialization tasks like installing dependencies or
|
||||
module "git-clone" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-clone/coder"
|
||||
version = "1.2.0"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
url = "https://github.com/coder/coder"
|
||||
post_clone_script = <<-EOT
|
||||
|
||||
@@ -60,7 +60,7 @@ if [ -n "$POST_CLONE_SCRIPT" ]; then
|
||||
echo "Running post-clone script..."
|
||||
echo "$POST_CLONE_SCRIPT" | base64 -d > /tmp/post_clone.sh
|
||||
chmod +x /tmp/post_clone.sh
|
||||
cd "$CLONE_PATH"
|
||||
cd "$CLONE_PATH" || exit
|
||||
/tmp/post_clone.sh
|
||||
rm /tmp/post_clone.sh
|
||||
fi
|
||||
|
||||
@@ -22,7 +22,7 @@ This module has a chance of conflicting with the user's dotfiles / the personali
|
||||
module "git-commit-signing" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-commit-signing/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -14,8 +14,8 @@ Runs a script that updates git credentials in the workspace to match the user's
|
||||
module "git-config" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-config/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -29,8 +29,8 @@ TODO: Add screenshot
|
||||
module "git-config" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-config/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.main.id
|
||||
allow_email_change = true
|
||||
}
|
||||
```
|
||||
@@ -43,8 +43,8 @@ TODO: Add screenshot
|
||||
module "git-config" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/git-config/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.main.id
|
||||
allow_username_change = false
|
||||
allow_email_change = false
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ Templates that utilize Github External Auth can automatically ensure that the Co
|
||||
module "github-upload-public-key" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/github-upload-public-key/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -47,8 +47,8 @@ data "coder_external_auth" "github" {
|
||||
module "github-upload-public-key" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/github-upload-public-key/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.main.id
|
||||
external_auth_id = data.coder_external_auth.github.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -13,8 +13,8 @@ Run the [Goose](https://block.github.io/goose/) agent in your workspace to gener
|
||||
```tf
|
||||
module "goose" {
|
||||
source = "registry.coder.com/coder/goose/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder"
|
||||
install_goose = true
|
||||
goose_version = "v1.0.31"
|
||||
@@ -39,7 +39,7 @@ module "coder-login" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/coder-login/coder"
|
||||
version = "1.0.15"
|
||||
agent_id = coder_agent.example.id
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
|
||||
variable "anthropic_api_key" {
|
||||
@@ -79,8 +79,8 @@ resource "coder_agent" "main" {
|
||||
module "goose" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/goose/coder"
|
||||
version = "3.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "3.0.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder"
|
||||
install_goose = true
|
||||
goose_version = "v1.0.31"
|
||||
|
||||
@@ -26,8 +26,8 @@ This module lets you fetch all or selective secrets from a [HCP Vault Secrets](h
|
||||
```tf
|
||||
module "vault" {
|
||||
source = "registry.coder.com/coder/hcp-vault-secrets/coder"
|
||||
version = "1.0.34"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.35"
|
||||
agent_id = coder_agent.main.id
|
||||
app_name = "demo-app"
|
||||
project_id = "aaa-bbb-ccc"
|
||||
}
|
||||
@@ -52,8 +52,8 @@ To fetch all secrets from the HCP Vault Secrets app, skip the `secrets` input.
|
||||
```tf
|
||||
module "vault" {
|
||||
source = "registry.coder.com/coder/hcp-vault-secrets/coder"
|
||||
version = "1.0.34"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.35"
|
||||
agent_id = coder_agent.main.id
|
||||
app_name = "demo-app"
|
||||
project_id = "aaa-bbb-ccc"
|
||||
}
|
||||
@@ -66,8 +66,8 @@ To fetch selective secrets from the HCP Vault Secrets app, set the `secrets` inp
|
||||
```tf
|
||||
module "vault" {
|
||||
source = "registry.coder.com/coder/hcp-vault-secrets/coder"
|
||||
version = "1.0.34"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.35"
|
||||
agent_id = coder_agent.main.id
|
||||
app_name = "demo-app"
|
||||
project_id = "aaa-bbb-ccc"
|
||||
secrets = ["MY_SECRET_1", "MY_SECRET_2"]
|
||||
@@ -81,8 +81,8 @@ Set `client_id` and `client_secret` as module inputs.
|
||||
```tf
|
||||
module "vault" {
|
||||
source = "registry.coder.com/coder/hcp-vault-secrets/coder"
|
||||
version = "1.0.34"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.35"
|
||||
agent_id = coder_agent.main.id
|
||||
app_name = "demo-app"
|
||||
project_id = "aaa-bbb-ccc"
|
||||
client_id = "HCP_CLIENT_ID"
|
||||
|
||||
@@ -16,8 +16,8 @@ JetBrains Fleet is a next-generation IDE that supports collaborative development
|
||||
module "jetbrains_fleet" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-fleet/coder"
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -37,8 +37,8 @@ module "jetbrains_fleet" {
|
||||
module "jetbrains_fleet" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-fleet/coder"
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -48,8 +48,8 @@ module "jetbrains_fleet" {
|
||||
module "jetbrains_fleet" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-fleet/coder"
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
```
|
||||
@@ -60,8 +60,8 @@ module "jetbrains_fleet" {
|
||||
module "jetbrains_fleet" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-fleet/coder"
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
display_name = "Fleet"
|
||||
group = "JetBrains IDEs"
|
||||
order = 1
|
||||
@@ -74,8 +74,8 @@ module "jetbrains_fleet" {
|
||||
module "jetbrains_fleet" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-fleet/coder"
|
||||
version = "1.0.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
agent_name = coder_agent.example.name
|
||||
}
|
||||
```
|
||||
|
||||
@@ -20,8 +20,8 @@ Consult the [JetBrains documentation](https://www.jetbrains.com/help/idea/prereq
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.5"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.6"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["CL", "GO", "IU", "PY", "WS"]
|
||||
default = "GO"
|
||||
@@ -38,8 +38,8 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.5"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.6"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["GO", "WS"]
|
||||
default = "GO"
|
||||
@@ -52,8 +52,8 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.5"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.6"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["IU", "PY"]
|
||||
default = "IU"
|
||||
@@ -67,8 +67,8 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.5"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.6"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["IU", "PY"]
|
||||
default = "IU"
|
||||
@@ -76,8 +76,9 @@ module "jetbrains_gateway" {
|
||||
jetbrains_ide_versions = {
|
||||
"IU" = {
|
||||
build_number = "243.21565.193"
|
||||
version = "2024.3"
|
||||
version = "1.2.6"
|
||||
}
|
||||
|
||||
"PY" = {
|
||||
build_number = "243.21565.199"
|
||||
version = "2024.3"
|
||||
@@ -92,8 +93,8 @@ module "jetbrains_gateway" {
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.5"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.6"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["GO", "WS"]
|
||||
default = "GO"
|
||||
@@ -110,8 +111,8 @@ Due to the highest priority of the `ide_download_link` parameter in the `(jetbra
|
||||
module "jetbrains_gateway" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains-gateway/coder"
|
||||
version = "1.2.5"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.6"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/example"
|
||||
jetbrains_ides = ["GO", "WS"]
|
||||
releases_base_link = "https://releases.internal.site/"
|
||||
|
||||
@@ -14,8 +14,8 @@ This module adds JetBrains IDE buttons to launch IDEs directly from the dashboar
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
# tooltip = "You need to [Install Coder Desktop](https://coder.com/docs/user-guides/desktop#install-coder-desktop) to use this button." # Optional
|
||||
}
|
||||
@@ -40,8 +40,8 @@ When `default` contains IDE codes, those IDEs are created directly without user
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["PY", "IU"] # Pre-configure GoLand and IntelliJ IDEA
|
||||
}
|
||||
@@ -53,8 +53,8 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
# Show parameter with limited options
|
||||
options = ["IU", "PY"] # Only these IDEs are available for selection
|
||||
@@ -67,8 +67,8 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["IU", "PY"]
|
||||
channel = "eap" # Use Early Access Preview versions
|
||||
@@ -82,8 +82,8 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
# Custom IDE metadata (display names and icons)
|
||||
@@ -93,6 +93,7 @@ module "jetbrains" {
|
||||
icon = "/custom/icons/intellij.svg"
|
||||
build = "251.26927.53"
|
||||
}
|
||||
|
||||
"PY" = {
|
||||
name = "PyCharm"
|
||||
icon = "/custom/icons/pycharm.svg"
|
||||
@@ -108,8 +109,8 @@ module "jetbrains" {
|
||||
module "jetbrains_pycharm" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
default = ["PY"] # Only PyCharm
|
||||
@@ -128,8 +129,8 @@ Add helpful tooltip text that appears when users hover over the IDE app buttons:
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["IU", "PY"]
|
||||
tooltip = "You need to [Install Coder Desktop](https://coder.com/docs/user-guides/desktop#install-coder-desktop) to use this button."
|
||||
|
||||
@@ -16,8 +16,8 @@ Install the JF CLI and authenticate package managers with Artifactory using OAut
|
||||
module "jfrog" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jfrog-oauth/coder"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.main.id
|
||||
jfrog_url = "https://example.jfrog.io"
|
||||
username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"
|
||||
|
||||
@@ -29,6 +29,7 @@ module "jfrog" {
|
||||
conda = ["conda", "conda-local"]
|
||||
maven = ["maven", "maven-local"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@@ -56,14 +57,15 @@ Configure the Python pip package manager to fetch packages from Artifactory whil
|
||||
module "jfrog" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jfrog-oauth/coder"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.main.id
|
||||
jfrog_url = "https://example.jfrog.io"
|
||||
username_field = "email"
|
||||
|
||||
package_managers = {
|
||||
pypi = ["pypi"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@@ -85,8 +87,8 @@ The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extensio
|
||||
module "jfrog" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jfrog-oauth/coder"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.3"
|
||||
agent_id = coder_agent.main.id
|
||||
jfrog_url = "https://example.jfrog.io"
|
||||
username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"
|
||||
configure_code_server = true # Add JFrog extension configuration for code-server
|
||||
@@ -95,6 +97,7 @@ module "jfrog" {
|
||||
go = ["go"]
|
||||
pypi = ["pypi"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ Install the JF CLI and authenticate package managers with Artifactory using Arti
|
||||
```tf
|
||||
module "jfrog" {
|
||||
source = "registry.coder.com/coder/jfrog-token/coder"
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.main.id
|
||||
jfrog_url = "https://XXXX.jfrog.io"
|
||||
artifactory_access_token = var.artifactory_access_token
|
||||
package_managers = {
|
||||
@@ -25,6 +25,7 @@ module "jfrog" {
|
||||
conda = ["conda", "conda-local"]
|
||||
maven = ["maven", "maven-local"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@@ -42,8 +43,8 @@ For detailed instructions, please see this [guide](https://coder.com/docs/v2/lat
|
||||
```tf
|
||||
module "jfrog" {
|
||||
source = "registry.coder.com/coder/jfrog-token/coder"
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.main.id
|
||||
jfrog_url = "https://YYYY.jfrog.io"
|
||||
artifactory_access_token = var.artifactory_access_token # An admin access token
|
||||
package_managers = {
|
||||
@@ -53,6 +54,7 @@ module "jfrog" {
|
||||
conda = ["conda-local"]
|
||||
maven = ["maven-local"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@@ -81,8 +83,8 @@ The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extensio
|
||||
```tf
|
||||
module "jfrog" {
|
||||
source = "registry.coder.com/coder/jfrog-token/coder"
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.main.id
|
||||
jfrog_url = "https://XXXX.jfrog.io"
|
||||
artifactory_access_token = var.artifactory_access_token
|
||||
configure_code_server = true # Add JFrog extension configuration for code-server
|
||||
@@ -91,6 +93,7 @@ module "jfrog" {
|
||||
go = ["go"]
|
||||
pypi = ["pypi"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@@ -101,14 +104,15 @@ data "coder_workspace" "me" {}
|
||||
|
||||
module "jfrog" {
|
||||
source = "registry.coder.com/coder/jfrog-token/coder"
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.main.id
|
||||
jfrog_url = "https://XXXX.jfrog.io"
|
||||
artifactory_access_token = var.artifactory_access_token
|
||||
token_description = "Token for Coder workspace: ${data.coder_workspace_owner.me.name}/${data.coder_workspace.me.name}"
|
||||
package_managers = {
|
||||
npm = ["npm"]
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ A module that adds Jupyter Notebook in your Coder template.
|
||||
module "jupyter-notebook" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jupyter-notebook/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -16,8 +16,8 @@ A module that adds JupyterLab in your Coder template.
|
||||
module "jupyterlab" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jupyterlab/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -29,8 +29,8 @@ JupyterLab is automatically configured to work with Coder's iframe embedding. Fo
|
||||
module "jupyterlab" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jupyterlab/coder"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.1"
|
||||
agent_id = coder_agent.main.id
|
||||
config = {
|
||||
ServerApp = {
|
||||
# Required for Coder Tasks iFrame embedding - do not remove
|
||||
@@ -38,6 +38,7 @@ module "jupyterlab" {
|
||||
headers = {
|
||||
"Content-Security-Policy" = "frame-ancestors 'self' ${data.coder_workspace.me.access_url}"
|
||||
}
|
||||
|
||||
}
|
||||
# Your additional configuration here
|
||||
root_dir = "/workspace/notebooks"
|
||||
|
||||
@@ -14,7 +14,7 @@ Automatically install [KasmVNC](https://kasmweb.com/kasmvnc) in a workspace, and
|
||||
module "kasmvnc" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/kasmvnc/coder"
|
||||
version = "1.2.5"
|
||||
version = "1.2.6"
|
||||
agent_id = coder_agent.example.id
|
||||
desktop_environment = "xfce"
|
||||
subdomain = true
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Exit on error, undefined variables, and pipe failures
|
||||
set -euo pipefail
|
||||
set -eo pipefail
|
||||
|
||||
error() {
|
||||
printf "💀 ERROR: %s\n" "$@"
|
||||
@@ -121,6 +120,9 @@ fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source /etc/os-release
|
||||
|
||||
set -u
|
||||
|
||||
distro="$ID"
|
||||
distro_version="$VERSION_ID"
|
||||
codename="$VERSION_CODENAME"
|
||||
|
||||
@@ -18,8 +18,8 @@ Uses the [Coder Remote VS Code Extension](https://github.com/coder/vscode-coder)
|
||||
module "kiro" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/kiro/coder"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -31,8 +31,8 @@ module "kiro" {
|
||||
module "kiro" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/kiro/coder"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
```
|
||||
@@ -47,8 +47,8 @@ The following example configures Kiro to use the GitHub MCP server with authenti
|
||||
module "kiro" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/kiro/coder"
|
||||
version = "1.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.main.id
|
||||
folder = "/home/coder/project"
|
||||
mcp = jsonencode({
|
||||
mcpServers = {
|
||||
@@ -59,6 +59,8 @@ module "kiro" {
|
||||
},
|
||||
"type" : "http"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,11 +17,6 @@ run "default_output" {
|
||||
condition = output.kiro_url == "kiro://coder.coder-remote/open?owner=default&workspace=default&url=https://mydeployment.coder.com&token=$SESSION_TOKEN"
|
||||
error_message = "Default kiro_url must match expected value"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = coder_app.kiro.order == null
|
||||
error_message = "coder_app order must be null by default"
|
||||
}
|
||||
}
|
||||
|
||||
run "adds_folder" {
|
||||
@@ -53,54 +48,6 @@ run "folder_and_open_recent" {
|
||||
}
|
||||
}
|
||||
|
||||
run "custom_slug_display_name" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "foo"
|
||||
slug = "kiro-ai"
|
||||
display_name = "Kiro AI IDE"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = coder_app.kiro.slug == "kiro-ai"
|
||||
error_message = "coder_app slug must be set to kiro-ai"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = coder_app.kiro.display_name == "Kiro AI IDE"
|
||||
error_message = "coder_app display_name must be set to Kiro AI IDE"
|
||||
}
|
||||
}
|
||||
|
||||
run "sets_order" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "foo"
|
||||
order = 5
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = coder_app.kiro.order == 5
|
||||
error_message = "coder_app order must be set to 5"
|
||||
}
|
||||
}
|
||||
|
||||
run "sets_group" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "foo"
|
||||
group = "AI IDEs"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = coder_app.kiro.group == "AI IDEs"
|
||||
error_message = "coder_app group must be set to AI IDEs"
|
||||
}
|
||||
}
|
||||
|
||||
run "writes_mcp_json" {
|
||||
command = plan
|
||||
|
||||
|
||||
@@ -26,7 +26,10 @@ describe("kiro", async () => {
|
||||
);
|
||||
|
||||
const coder_app = state.resources.find(
|
||||
(res) => res.type === "coder_app" && res.name === "kiro",
|
||||
(res) =>
|
||||
res.type === "coder_app" &&
|
||||
res.module === "module.vscode-desktop-core" &&
|
||||
res.name === "vscode-desktop",
|
||||
);
|
||||
|
||||
expect(coder_app).not.toBeNull();
|
||||
@@ -55,47 +58,6 @@ describe("kiro", async () => {
|
||||
);
|
||||
});
|
||||
|
||||
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");
|
||||
});
|
||||
|
||||
it("writes ~/.kiro/settings/mcp.json when mcp provided", async () => {
|
||||
const id = await runContainer("alpine");
|
||||
try {
|
||||
|
||||
@@ -38,18 +38,6 @@ variable "group" {
|
||||
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"
|
||||
}
|
||||
|
||||
variable "mcp" {
|
||||
type = string
|
||||
description = "JSON-encoded string to configure MCP servers for Kiro. When set, writes ~/.kiro/settings/mcp.json."
|
||||
@@ -63,26 +51,21 @@ locals {
|
||||
mcp_b64 = var.mcp != "" ? base64encode(var.mcp) : ""
|
||||
}
|
||||
|
||||
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",
|
||||
])
|
||||
module "vscode-desktop-core" {
|
||||
source = "registry.coder.com/coder/vscode-desktop-core/coder"
|
||||
version = "1.0.0"
|
||||
|
||||
agent_id = var.agent_id
|
||||
|
||||
coder_app_icon = "/icon/kiro.svg"
|
||||
coder_app_slug = "kiro-ai"
|
||||
coder_app_display_name = "Kiro AI IDE"
|
||||
coder_app_order = var.order
|
||||
coder_app_group = var.group
|
||||
|
||||
folder = var.folder
|
||||
open_recent = var.open_recent
|
||||
protocol = "kiro"
|
||||
}
|
||||
|
||||
resource "coder_script" "kiro_mcp" {
|
||||
@@ -102,6 +85,6 @@ resource "coder_script" "kiro_mcp" {
|
||||
}
|
||||
|
||||
output "kiro_url" {
|
||||
value = coder_app.kiro.url
|
||||
value = module.vscode-desktop-core.ide_uri
|
||||
description = "Kiro IDE URL."
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ This module enables Remote Desktop Protocol (RDP) on Windows workspaces and adds
|
||||
module "rdp_desktop" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/local-windows-rdp/coder"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
agent_id = coder_agent.main.id
|
||||
agent_name = coder_agent.main.name
|
||||
}
|
||||
@@ -57,7 +57,7 @@ Uses default credentials (Username: `Administrator`, Password: `coderRDP!`):
|
||||
module "rdp_desktop" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/local-windows-rdp/coder"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
agent_id = coder_agent.main.id
|
||||
agent_name = coder_agent.main.name
|
||||
}
|
||||
@@ -71,8 +71,8 @@ Specify a custom display name for the `coder_app` button:
|
||||
module "rdp_desktop" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/local-windows-rdp/coder"
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.windows.id
|
||||
version = "1.0.3"
|
||||
agent_id = coder_agent.main.id
|
||||
agent_name = "windows"
|
||||
display_name = "Windows Desktop"
|
||||
order = 1
|
||||
|
||||
@@ -14,8 +14,8 @@ Automatically install and run mux in a Coder workspace. By default, the module i
|
||||
module "mux" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/mux/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -35,8 +35,8 @@ module "mux" {
|
||||
module "mux" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/mux/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -46,8 +46,8 @@ module "mux" {
|
||||
module "mux" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/mux/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
# Default is "latest"; set to a specific version to pin
|
||||
install_version = "0.4.0"
|
||||
}
|
||||
@@ -59,8 +59,8 @@ module "mux" {
|
||||
module "mux" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/mux/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
port = 8080
|
||||
}
|
||||
```
|
||||
@@ -73,8 +73,8 @@ Run an existing copy of mux if found, otherwise install from npm:
|
||||
module "mux" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/mux/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
use_cached = true
|
||||
}
|
||||
```
|
||||
@@ -87,8 +87,8 @@ Run without installing from the network (requires mux to be pre-installed):
|
||||
module "mux" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/mux/coder"
|
||||
version = "1.0.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.main.id
|
||||
install = false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -55,6 +55,7 @@ describe("mux", async () => {
|
||||
expect(output.exitCode).toBe(0);
|
||||
const expectedLines = [
|
||||
"📦 Installing mux via npm into /tmp/mux...",
|
||||
"⏭️ Skipping npm lifecycle scripts with --ignore-scripts",
|
||||
"🥳 mux has been installed in /tmp/mux",
|
||||
"🚀 Starting mux server on port 4000...",
|
||||
"Check logs at /tmp/mux.log!",
|
||||
@@ -62,5 +63,5 @@ describe("mux", async () => {
|
||||
for (const line of expectedLines) {
|
||||
expect(output.stdout).toContain(line);
|
||||
}
|
||||
}, 60000);
|
||||
}, 180000);
|
||||
});
|
||||
|
||||
@@ -50,13 +50,14 @@ if [ ! -f "$MUX_BINARY" ] || [ "${USE_CACHED}" != true ]; then
|
||||
if [ ! -f package.json ]; then
|
||||
echo '{}' > package.json
|
||||
fi
|
||||
echo "⏭️ Skipping npm lifecycle scripts with --ignore-scripts"
|
||||
PKG="mux"
|
||||
if [ -z "${VERSION}" ] || [ "${VERSION}" = "latest" ]; then
|
||||
PKG_SPEC="$PKG@latest"
|
||||
else
|
||||
PKG_SPEC="$PKG@${VERSION}"
|
||||
fi
|
||||
if ! npm install --no-audit --no-fund --omit=dev "$PKG_SPEC"; then
|
||||
if ! npm install --no-audit --no-fund --omit=dev --ignore-scripts "$PKG_SPEC"; then
|
||||
echo "❌ Failed to install mux via npm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -14,7 +14,7 @@ Run a script on workspace start that allows developers to run custom commands to
|
||||
module "personalize" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/personalize/coder"
|
||||
version = "1.0.31"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ Deploy the Rocker Project distribution of RStudio Server in your Coder workspace
|
||||
module "rstudio-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/rstudio-server/coder"
|
||||
version = "0.9.0"
|
||||
agent_id = coder_agent.example.id
|
||||
version = "0.9.1"
|
||||
agent_id = coder_agent.main.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -14,7 +14,7 @@ Add the `slackme` command to your workspace that DMs you on Slack when your comm
|
||||
module "slackme" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/slackme/coder"
|
||||
version = "1.0.31"
|
||||
version = "1.0.33"
|
||||
agent_id = coder_agent.example.id
|
||||
auth_provider_id = "slack"
|
||||
}
|
||||
@@ -74,7 +74,7 @@ slackme npm run long-build
|
||||
module "slackme" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/slackme/coder"
|
||||
version = "1.0.31"
|
||||
version = "1.0.33"
|
||||
agent_id = coder_agent.example.id
|
||||
auth_provider_id = "slack"
|
||||
slack_message = <<EOF
|
||||
|
||||
@@ -73,13 +73,13 @@ fi
|
||||
|
||||
START=$(date +%s%N)
|
||||
# Run all arguments as a command
|
||||
$@
|
||||
"$@"
|
||||
END=$(date +%s%N)
|
||||
DURATION_MS=$${DURATION_MS:-$(((END - START) / 1000000))}
|
||||
PRETTY_DURATION=$(pretty_duration $DURATION_MS)
|
||||
|
||||
set -e
|
||||
COMMAND=$(echo $@)
|
||||
COMMAND=$(echo "$@")
|
||||
SLACK_MESSAGE=$(echo "$SLACK_MESSAGE" | sed "s|\\$COMMAND|$COMMAND|g")
|
||||
SLACK_MESSAGE=$(echo "$SLACK_MESSAGE" | sed "s|\\$DURATION|$PRETTY_DURATION|g")
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ This module lets you authenticate with [Hashicorp Vault](https://www.vaultprojec
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-github/coder"
|
||||
version = "1.0.31"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
}
|
||||
@@ -46,7 +46,7 @@ To configure the Vault module, you must set up a Vault GitHub auth method. See t
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-github/coder"
|
||||
version = "1.0.31"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
coder_github_auth_id = "my-github-auth-id"
|
||||
@@ -59,7 +59,7 @@ module "vault" {
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-github/coder"
|
||||
version = "1.0.31"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
coder_github_auth_id = "my-github-auth-id"
|
||||
@@ -73,9 +73,9 @@ module "vault" {
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-github/coder"
|
||||
version = "1.0.31"
|
||||
version = "1.1.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
vault_cli_version = "1.15.0"
|
||||
vault_cli_version = "1.1.2"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -32,6 +32,12 @@ variable "vault_github_auth_path" {
|
||||
default = "github"
|
||||
}
|
||||
|
||||
variable "vault_namespace" {
|
||||
type = string
|
||||
description = "The Vault Enterprise namespace that contains the GitHub auth mount."
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "vault_cli_version" {
|
||||
type = string
|
||||
description = "The version of Vault to install."
|
||||
@@ -52,6 +58,7 @@ resource "coder_script" "vault" {
|
||||
AUTH_PATH : var.vault_github_auth_path,
|
||||
GITHUB_EXTERNAL_AUTH_ID : data.coder_external_auth.github.id,
|
||||
INSTALL_VERSION : var.vault_cli_version,
|
||||
VAULT_NAMESPACE : var.vault_namespace != null ? var.vault_namespace : "",
|
||||
})
|
||||
run_on_start = true
|
||||
start_blocks_login = true
|
||||
@@ -63,6 +70,13 @@ resource "coder_env" "vault_addr" {
|
||||
value = var.vault_addr
|
||||
}
|
||||
|
||||
resource "coder_env" "vault_namespace" {
|
||||
count = var.vault_namespace == null ? 0 : 1
|
||||
agent_id = var.agent_id
|
||||
name = "VAULT_NAMESPACE"
|
||||
value = var.vault_namespace
|
||||
}
|
||||
|
||||
data "coder_external_auth" "github" {
|
||||
id = var.coder_github_auth_id
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
INSTALL_VERSION=${INSTALL_VERSION}
|
||||
GITHUB_EXTERNAL_AUTH_ID=${GITHUB_EXTERNAL_AUTH_ID}
|
||||
AUTH_PATH=${AUTH_PATH}
|
||||
VAULT_NAMESPACE=${VAULT_NAMESPACE}
|
||||
|
||||
fetch() {
|
||||
dest="$1"
|
||||
@@ -46,6 +47,7 @@ install() {
|
||||
if [ "$${INSTALL_VERSION}" = "latest" ]; then
|
||||
LATEST_VERSION=$(curl -s https://releases.hashicorp.com/vault/ | grep -v 'rc' | grep -oE 'vault/[0-9]+\.[0-9]+\.[0-9]+' | sed 's/vault\///' | sort -V | tail -n 1)
|
||||
printf "Latest version of Vault is %s.\n\n" "$${LATEST_VERSION}"
|
||||
# shellcheck disable=SC2157
|
||||
if [ -z "$${LATEST_VERSION}" ]; then
|
||||
printf "Failed to determine the latest Vault version.\n"
|
||||
return 1
|
||||
@@ -63,8 +65,10 @@ install() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2170
|
||||
if [ $${installation_needed} -eq 1 ]; then
|
||||
# Download and install Vault
|
||||
# shellcheck disable=SC2157
|
||||
if [ -z "$${CURRENT_VERSION}" ]; then
|
||||
printf "Installing Vault CLI ...\n\n"
|
||||
else
|
||||
@@ -104,6 +108,11 @@ if ! (
|
||||
fi
|
||||
rm -rf "$TMP"
|
||||
|
||||
if [ -n "$${VAULT_NAMESPACE}" ]; then
|
||||
export VAULT_NAMESPACE
|
||||
printf "📁 Using Vault namespace: %s\n\n" "$${VAULT_NAMESPACE}"
|
||||
fi
|
||||
|
||||
# Authenticate with Vault
|
||||
printf "🔑 Authenticating with Vault ...\n\n"
|
||||
GITHUB_TOKEN=$(coder external-auth access-token "$${GITHUB_EXTERNAL_AUTH_ID}")
|
||||
|
||||
@@ -14,7 +14,7 @@ This module lets you authenticate with [Hashicorp Vault](https://www.vaultprojec
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-jwt/coder"
|
||||
version = "1.1.1"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
vault_jwt_role = "coder" # The Vault role to use for authentication
|
||||
@@ -42,7 +42,7 @@ curl -H "X-Vault-Token: ${VAULT_TOKEN}" -X GET "${VAULT_ADDR}/v1/coder/secrets/d
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-jwt/coder"
|
||||
version = "1.1.1"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
vault_jwt_auth_path = "oidc"
|
||||
@@ -58,7 +58,7 @@ data "coder_workspace_owner" "me" {}
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-jwt/coder"
|
||||
version = "1.1.1"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
vault_jwt_role = data.coder_workspace_owner.me.groups[0]
|
||||
@@ -71,11 +71,11 @@ module "vault" {
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-jwt/coder"
|
||||
version = "1.1.1"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
vault_jwt_role = "coder" # The Vault role to use for authentication
|
||||
vault_cli_version = "1.17.5"
|
||||
vault_cli_version = "1.2.2"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -87,11 +87,11 @@ terraform {
|
||||
required_providers {
|
||||
jwt = {
|
||||
source = "geektheripper/jwt"
|
||||
version = "1.1.4"
|
||||
version = "1.2.2"
|
||||
}
|
||||
time = {
|
||||
source = "hashicorp/time"
|
||||
version = "0.11.1"
|
||||
version = "1.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ resource "jwt_signed_token" "vault" {
|
||||
module "vault" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vault-jwt/coder"
|
||||
version = "1.1.1"
|
||||
version = "1.2.2"
|
||||
agent_id = coder_agent.example.id
|
||||
vault_addr = "https://vault.example.com"
|
||||
vault_jwt_role = "coder" # The Vault role to use for authentication
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user